Spring MVC, JDBC DataSourceTransactionManager: Daten verpflichtet, auch nach readonly=true
Ich bin derzeit an der Entwicklung einer Spring-MVC-Anwendung.Ich habe die Konfiguration eines JDBC-TransactionManager und ich mache deklaratives Transaktionsmanagement mit AOP XML.Jedoch, selbst wenn ich die Methode konfigurieren, die zur Ausführung auf einem read-only=true, ist es immer noch die Transaktion ein commit ausgeführt.
Datenbank : Oracle 10g
Meine database-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schem...ring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:com/mybatis/mappers/*.xml" />
</bean>
<!--
the transactional advice (what 'happens'; see the <aop:advisor/> bean
below)
-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true" />
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" read-only="true" rollback-for="RuntimeException"/>
</tx:attributes>
</tx:advice>
<!--
ensure that the above transactional advice runs for any execution of
an operation defined by the FooService interface
-->
<aop:config>
<aop:pointcut id="fooServiceOperation"
expression="execution(* com.service.EmployeeService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation" />
</aop:config>
</beans>
Mein controller
package com.service;
import java.util.List;
import com.mybatis.dao.EmployeeMapperInterface;
import com.spring.model.Employee;
public class EmployeeService implements EmployeeBaseService{
EmployeeMapperInterface employeeMapper;
public EmployeeMapperInterface getEmployeeMapper() {
return employeeMapper;
}
public void setEmployeeMapper(EmployeeMapperInterface employeeMapper) {
this.employeeMapper = employeeMapper;
}
@Override
public Employee getEmployeeById(long empId){
//retrieve from database
List empList = employeeMapper.getEmployeeWithId(empId);
if(empList != null && empList.size()>0){
return (Employee) empList.get(0);
}
return null;
}
@Override
public long saveEmployee(Employee employee){
long empId = 0l;
if(employee.getEmpId()==0){
empId = new Long( employeeMapper.insertEmployee(employee));
}else{
employeeMapper.updateEmployee(employee);
empId = employee.getEmpId();
}
try {
System.out.println("gonna sleep");
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return empId;
}
Wie kann ich verhindern, dass das auto übernehmen?Ich habe auch bemerkt, dass, auch wenn ich nicht jede Transaktion-management-code, der code immer noch begeht. Beachten Sie, dass die Transaktion beraten ist jedoch,die aufgerufen wird, als wenn ich einen no-rollback-for für RuntimeException-und dann 1/0, es korrekt übernimmt die Daten und rollt sich zurück, wenn ich das gleiche wie rollback-für.
Ich habe auch versucht, aus den Abfrage-timeout, indem Sie den Faden auf den Schlaf, auch das funktioniert nicht, aber ich vermute, dass der timeout für eine tatsächliche Abfrage, also ist das in Ordnung.
Vielen Dank im Voraus!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Rat
read-only
ist nur Beratung. Es ist nicht Voraussetzung, dass die zugrunde liegende Transaktion-management-system zu verhindern, schreibt, wenn etwas markiert istread-only
es gemeint ist mehr als eine Optimierung Hinweis, sagen, dass diese Methode ist nur zu Lesen, so brauchen Sie nicht zu kümmern, Dinge zu verändern. Einige Transaktions-Manager beklagen, wenn änderungen vorgenommen werden, die in einem nur-lese-Transaktion, manche nicht. Generelldatasource
s erworben, über JNDI nicht. In jedem Fall sollte man sich nicht verlassen aufread-only
Beratung zur Verhinderung von änderungen wird auf den Datenträger zurückgeschrieben.Ihre Optionen für die Verhinderung von änderungen aus beibehalten wird, sind:
Markieren Sie die Transaktion
rollback only
oder wirft eine exception mit der gleichen WirkungLösen/entfernen Sie den Gegenstand aus der Transaktion Sitzung, bevor Sie es ändern
Klonen Sie das Objekt und verwenden Sie das Klon -
DataSourceTransactionManager
beginnt die Transaktion mitdoBegin
- Methode.Von dieser Methode
DataSourceUtils.prepareConnectionForTransaction
genannt.Innerhalb dieser Methode können Sie sehen folgenden code-block:
So dass Sie konfigurieren können Ihre logging-framework zu set log-level auf DEBUG für
DataSourceUtils
Klasse.Oder Sie können einen Haltepunkt und debug manuell.
Gemäß dieser Artikel ich erwarte, dass
SET TRANSACTION READ ONLY
ausgeführt werden, die auf Ihre Oracle-Verbindung.Und von Oracle docs konnten wir sehen, die Vorteile, die Sie erhalten, im Falle des Erfolgs:
Den nur-lese-Verhalten ist streng Treiber. Oracle-Treiber ignoriert dieses flag ganz. Zum Beispiel die gleichen update-Anweisungen ausgeführt, die in Oracle wird die Datenbank ändern wenn Sie im nur-Lesen-Transaktion, während in HSQL2 war ich immer zu db-Pegel Ausnahmen.
Ich weiß keine andere Möglichkeit, als explizite rollback, über api oder eine exception zu verhindern, dass commit in Oracle. Auch auf diese Weise Ihr code portabel zwischen verschiedenen Treibern und Datenbanken.
Ist die Antwort auf Spring MVC Mybatis Transaktion commit
Detaillierte stack-traces sind auch verfügbar.
Zusammenfassend ist zu sagen,
wirklich wie die Feder docs aktualisiert werden, über diese.
commit(oder Rollback, wenn execption ausgelöst wird),geschlossen und durch
Mybatis.
.