1.前面有写过“数据库中的-脏读,幻读,不可重复读”,之所以要用到事务,也就是为了控制数据库的“锁”概念。地址是 http://blog.csdn.net/d8111/archive/2008/06/29/2595635.aspx
2.看spring文档,了解spring的5种事务级别,7种隔离级别。
二。总概
spinrg的编程风格非常一致,包括事务的配置及其他一些内容,均提供一下几种标准模式:
1.编程式注入事务:就是在代码中引入TransactionTemplate 模板显示调用模板方法。
如果不需要返回值,如下:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
updateOperation1();
updateOperation2();
}
});
回调方法内的代码可以通过调用 TransactionStatus 对象的 setRollbackOnly() 方法来回滚事务。
transactionTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { try { updateOperation1(); updateOperation2(); } catch (SomeBusinessExeption ex) { status.setRollbackOnly(); } } });
具体可以参考《The Spring Framework - Reference Documentation》,这里不难,但是也是最不推荐的一种方法。除非你需要精确控制一个方法中仅仅某几行加入事务,否则不推荐使用。
2。基于AOP的配置(通过spring的文档弄明白AOP是一个非常痛苦的事情,so many 概念,看起来十分复杂。而实际上,我们仅仅需要了解几行代码即可)。基于AOP的配置通常是用来处理批量事务。比如要讲所以get开头的方法加入readonly等等啦。。
<!----> <beans xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns="http://www.springframework.org/schema/beans"> <bean class="x.y.service.DefaultFooService" id="fooService"> <!----> <bean class="x.y.SimpleProfiler" id="profiler"> <!----> <property name="order" value="1"></property> </bean> <!----><tx:annotation-driven order="200" transaction-manager="txManager"></tx:annotation-driven> <!----><aop:config> <!----> <aop:aspect id="profilingAspect" ref="profiler"> <aop:pointcut id="serviceMethodWithReturnValue" expression="execution(!void x.y..*Service.*(..))"></aop:pointcut> <aop:around method="profile" pointcut-ref="serviceMethodWithReturnValue"></aop:around> </aop:aspect> </aop:config> <bean destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource" id="dataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property> <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"></property> <property name="username" value="scott"></property> <property name="password" value="tiger"></property> </bean> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager"> <property name="dataSource" ref="dataSource"></property> </bean> </bean></beans>
3。基于bean属性的xml注入配置方式。这种方式配置工作量比较大,建议使用方法4代替
1)将TransactionProxyFactoryBean声明成一个抽象bean,作为service层bean的基类,需要事务的bean集成此基类。
<!----> <beans default-autowire="byName"> <bean class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true" id="transactionParent"> <property name="transactionManager"><ref bean="transactionManager"></ref></property> </bean> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource"> <ref local="dataSource"> </ref></property> </bean> </beans>
2)业务bean继承事务基类,覆盖父类属性“target”配置事务属性
<bean parent="transactionParent" id="dosomethingBean"> <property name="target"> <bean class="com.alisoft.xxxx"> </bean> <property name="transactionAttributes"> <props> <prop key="commitScore"> //方法名 PROPAGATION_REQUIRED </prop> </props> </property> </property></bean>
4。基于annotation事务(需要添加cglib包)。这是一种针对单个方法加入事务最easy,我也最推荐的方式了。
1)在spring基于 Schema的配置xml中加入:
<tx:annotation-driven transaction-manager="transactionManager"/>
他的作用是: 开启annotations模式的事务行为
2)然后,在需要加入事务的类/方法上使用注释@Transactional。属性直接配置
/** * 这个方法被加入了事务控制 * @param departmentId */ @Transactional(isolation=Isolation.SERIALIZABLE) public Integer getDepartmentArchiveCode(int departmentId) { }