事务属性的种类:传播行为,隔离级别,只读,事务超时
传播行为:定义了被调用方法的事务边界
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。 (required必须的)
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 (support支持,有就用,没有就不用)
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 (mandatory强制的,一定要有,没有就抛异常)
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 (new必须新建一个,有的话则挂起)
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 (notsupport不支持,有则挂起来)
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。 (never不能有,有则抛异常)
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 (mandatory强制的,一定要有,没有就抛异常)
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 (new必须新建一个,有的话则挂起)
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 (notsupport不支持,有则挂起来)
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。 (never不能有,有则抛异常)
PROPAGATION_NESTED-当前事务存在,则方法应该运行在一个嵌套事务中,否则和required没啥区别 (nested嵌套的,有则嵌套)
隔离级别:
简单来说就是一般会有三种副作用:脏读,不可重复读,幻读。
在mysql中有4种隔离级别:未提交读,已提交读,可重复读,可序列化。
Spring则提供5种隔离级别来对应它们:
ISOLATION_DEFAULT | 使用后端数据库默认的隔离级别 |
ISOLATION_READ_UNCOMMITTED | 允许读取未提交的数据(对应未提交读),可能导致脏读、不可重复读、幻读 |
ISOLATION_READ_COMMITTED | 允许在一个事务中读取另一个已经提交的事务中的数据(对应已提交读)。可以避免脏读,但是无法避免不可重复读和幻读 |
ISOLATION_REPEATABLE_READ | 一个事务不可能更新由另一个事务修改但尚未提交(回滚)的数据(对应可重复读)。可以避免脏读和不可重复读,但无法避免幻读 |
ISOLATION_SERIALIZABLE | 这种隔离级别是所有的事务都在一个执行队列中,依次顺序执行,而不是并行(对应可序列化)。可以避免脏读、不可重复读、幻读。但是这种隔离级别效率很低,因此,除非必须,否则不建议使用。 |
只读:
如果在一个事务中所有关于数据库的操作都是只读的,也就是说,这些操作只读取数据库中的数据,而并不更新数据,那么应将事务设为只读模式( READ_ONLY_MARKER ) , 这样更有利于数据库进行优化 。
因为只读的优化措施是事务启动后由数据库实施的,因此,只有将那些具有可能启动新事务的传播行为 (PROPAGATION_NESTED 、 PROPAGATION_REQUIRED 、 PROPAGATION_REQUIRED_NEW) 的方法的事务标记成只读才有意义。事务超时:
如果一个事务长时间运行,这时为了尽量避免浪费系统资源,应为这个事务设置一个有效时间,使其等待数秒后自动回滚。与设置“只读”属性一样,事务有效属性也需要给那些具有可能启动新事物的传播行为的方法的事务标记成只读才有意义。