一
在Spring中配置事务管理器
事务管理器bean的声明
?<bean id=transactionManager
class=orgspringframeworkormhibernateHibernateTransactionManager>
? <property name=sessionFactory ref=sessionFactory />
?bean>
如果你需要以标注驱动的方式管理的话必须在applicationContextxml中申明
<tx:annotationdriven transactionmanager=transactionManager/>
如果你用xml的方式使用事务管理器的话如下有一个例子
?<tx:advice id=txAdvice transactionmanager=transactionManager>
? <tx:attributes>
? <tx:method name=find* readonly=true/>
? <tx:method name=* propagation=REQUIRED/>
? tx:attributes>
?tx:advice>
??<aop:config>
? <aop:pointcut expression=execution(* *daoimpl*()) id=daopc/>
? <aop:pointcut expression=execution(* *serviceimpl*()) id=servicepc/>
? <aop:advisor adviceref=txAdvice pointcutref=daopc/>
? <aop:advisor adviceref=txAdvice pointcutref=servicepc/>
?aop:config>
?<aop:aspectjautoproxy />
二在java代码中指定事务属性(使用标注)
下面例子是Dao实现类的一个方法采用标注来指明事务
?@Transactional(readOnly=true)
?public List<User> findUser(UserDto dto) {
? User user = new User()
? pyProperties(dto user)
? return factorygetCurrentSession()
? createCriteria(Userclass)
? add(Examplecreate(user))
? list()
?}
三Spring事务选项默认的 @Transactional设置如下
· 事务传播设置是 PROPAGATION_REQUIRED 使用现有事物没有则启动新事物
· 事务隔离级别是 ISOLATION_DEFAULT
· 事务是 读/写 false
· 事务超时默认是依赖于事务系统的或者事务超时没有被支持
· 任何unchecked Exception将触发事务回滚但是任何checked Exception将触发事务提交
@Transactional注解的属性
· 传播性propagation 可选的传播性设置
· 隔离性isolation 可选的隔离性级别
· 只读性readOnly 读写型事务 or 只读型事务
· 回滚异常类rollbackFor 一组异常类遇到时必须进行回滚默认情况下checked exceptions不进行回滚而是提交仅unchecked exceptions才进行事务回滚
· 回滚异常类名rollbackForClassname 一组异常类名遇到时必须进行回滚
· 不回滚异常类noRollbackFor 一组异常类遇到时必须不回滚
· 不回滚异常类名noRollbackForClassname 一组异常类遇到时必须不回滚
Propagation
key属性确定代理应该给哪个方法增加事务行为这样的属性最重要的部份是传播行为有以下选项可供使用
· PROPAGATION_REQUIRED支持当前事务如果当前没有事务就新建一个事务这是最常见的选择
· PROPAGATION_SUPPORTS支持当前事务如果当前没有事务就以非事务方式执行
· PROPAGATION_MANDATORY支持当前事务如果当前没有事务就抛出异常
· PROPAGATION_REQUIRES_NEW新建事务如果当前存在事务把当前事务挂起
· PROPAGATION_NOT_SUPPORTED以非事务方式执行操作如果当前存在事务就把当前事务挂起
· PROPAGATION_NEVER以非事务方式执行如果当前存在事务则抛出异常
Isolation Level(事务隔离等级)
· Serializable:最严格的级别事务串行执行资源消耗最大
· REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据避免了髒读取和不可重复读取的情况但是带来了更多的性能损失
· READ COMMITTED:大多数主流数据库的默认事务等级保证了一个事务不会读到另一个并行事务已修改但未提交的数据避免了髒读取该级别适用于大多数系统
· Read Uncommitted:保证了读取过程中不会读取到非法数据
隔离级别在于处理多事务的并发问题我们知道并行可以提高数据库的吞吐量和效率但是并不是所有的并发事务都可以并发运行这需要查看数据库教材的可串行化条件判断了
我们首先说并发中可能发生的中不讨人喜欢的事情
· Dirty reads读髒数据也就是说比如事务A的未提交(还依然缓存)的数据被事务B读走如果事务A失败回滚会导致事务B所读取的的数据是错误的
· nonrepeatable reads数据不可重复读比如事务A中两处读取数据total的值在第一读的时候total是然后事务B就把total的数据改成事务A再读一次结果就发现total竟然就变成了造成事务A数据混乱
· phantom reads幻象读数据这个和nonrepeatable reads相似也是同一个事务中多次读不一致的问题但是nonrepeatable reads的不一致是因为他所要取的数据集被改变了(比如total的数据)但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变而是他的条件数据集改变比如Select accountid where accountname=ppgogo*第一次读去了个符合条件的id第二次读取的时候由于事务b把一个帐号的名字由dd改成ppgogo结果取出来了个数据
readOnly
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务这是一个最优化提示在一些情况下一些事务策略能够起到显着的最优化效果例如在使用Object/Relational映射工具(如Hibernate或TopLink)时避免dirty checking
readOny只是一种暗示具体会不会起到优化的效果还取决于数据库
Timeout
在事务属性中还有定义timeout值的选项指定事务超时为几秒在JTA中这将被简单地传递到JEE服务器的事务协调程序并据此得到相应的解释