介绍

1.声明式事务管理建立在AOP之上的. 其本质是对方法前后进行拦截, 然后在目标方法开始之前创建或者加入一个事务, 在执行完目标方法之后根据执行情况提交或者回滚事务.
2.声明式事务最大的优点就是不需要通过编程的方式管理事务, 这样就不需要在业务逻辑代码中掺杂事务管理的代码, 只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式), 便可以将事务规则应用到业务逻辑中.
3.声明式事务不足的地方在于, 与编程式事务相比, 只能作用到方法级别, 无法像编程式事务那样可以作用到代码块级别.

xml配置

1.添加命名空间

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. . . .
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="
  7. . . .
  8. http://www.springframework.org/schema/tx
  9. http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

2.添加相关事务支持

  1. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  2. <!-- 指向数据源 -->
  3. <property name="dataSource" ref="masterDataSource"/>
  4. </bean>
  5. <!-- 开启事务的Annotation支持 -->
  6. <tx:annotation-driven transaction-manager="transactionManager"/>

@Transactional注解 使用

_@_Transactional 可以作用于接口,接口方法,类以及类方法上. 只需要在相应接口,类或方法上加上@Transactional注解即可.

_@_Transactional 注解介绍

  1. package org.springframework.transaction.annotation;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Inherited;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. import org.springframework.core.annotation.AliasFor;
  9. import org.springframework.transaction.TransactionDefinition;
  10. import org.springframework.transaction.annotation.Isolation;
  11. import org.springframework.transaction.annotation.Propagation;
  12. /**
  13. * @Target({ElementType.METHOD, ElementType.TYPE}) : 可用于接口, 类, 枚举, 注解, 方法
  14. * @Retention(RetentionPolicy.RUNTIME) : 注解会在class字节码文件中存在,在运行时可以通过反射获取到
  15. * @Inherited : 子类可以继承父类中的注解
  16. * @Documented : 注解将被包含在javadoc中
  17. */
  18. @Target({ElementType.METHOD, ElementType.TYPE})
  19. @Retention(RetentionPolicy.RUNTIME)
  20. @Inherited
  21. @Documented
  22. public @interface Transactional {
  23. /**
  24. * 事务管理器的别名
  25. * 系统指定多个事务管理器时可通过别名进行区分
  26. */
  27. @AliasFor("transactionManager")
  28. String value() default "";
  29. /**
  30. * 可通过在 transactionManager 中设置 <qualifier value="managerOne"/> 属性类指定名称
  31. * 可用于确定目标事务管理器,匹配特定的限定符值(或bean名称)
  32. */
  33. @AliasFor("value")
  34. String transactionManager() default "";
  35. /**
  36. * 事务的传播机制
  37. * 默认 Propagation.REQUIRED
  38. */
  39. Propagation propagation() default Propagation.REQUIRED;
  40. /**
  41. * 事务的隔离级别
  42. * 默认 Isolation.DEFAULT
  43. */
  44. Isolation isolation() default Isolation.DEFAULT;
  45. /**
  46. * 事务超时时间
  47. * 默认 TransactionDefinition.TIMEOUT_DEFAULT 即 -1
  48. */
  49. int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
  50. /**
  51. * 设置事务只读
  52. */
  53. boolean readOnly() default false;
  54. /**
  55. * 设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚
  56. * rollbackFor = Exception.class 或 rollbackFor = {RuntimeException.class, Exception.class}
  57. */
  58. Class<? extends Throwable>[] rollbackFor() default {};
  59. /**
  60. * 设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时, 事务进行回滚
  61. */
  62. String[] rollbackForClassName() default {};
  63. /**
  64. * 设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则不进行事务回滚
  65. */
  66. Class<? extends Throwable>[] noRollbackFor() default {};
  67. /**
  68. * 设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时, 事务不进行回滚
  69. */
  70. String[] noRollbackForClassName() default {};
  71. }

传播行为介绍

事务的传播行为, 一共 7 种
1.枚举介绍

  1. package org.springframework.transaction.annotation;
  2. import org.springframework.transaction.TransactionDefinition;
  3. public enum Propagation {
  4. /**
  5. * 支持当前事务, 如果不存在, 则创建一个新事务
  6. * 事务的默认设置
  7. */
  8. REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
  9. /**
  10. * 支持当前事务, 如果不存在, 则以非事务方式执行
  11. */
  12. SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
  13. /**
  14. * 支持当前事务, 如果不存在则抛出异常
  15. */
  16. MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
  17. /**
  18. * 开始一个新的事务, 并暂停当前事务(如果存在)
  19. */
  20. REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
  21. /**
  22. * 以非事务方式执行, 暂停当前事务(如果存在)
  23. */
  24. NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
  25. /**
  26. * 以非事务方式执行, 如果存在则抛出异常
  27. */
  28. NEVER(TransactionDefinition.PROPAGATION_NEVER),
  29. /**
  30. * 如果当前事务存在, 则在嵌套事务中执行.
  31. * 如果事务不存在, 则等同于 PROPAGATION_REQUIRED
  32. */
  33. NESTED(TransactionDefinition.PROPAGATION_NESTED);
  34. private final int value;
  35. Propagation(int value) { this.value = value; }
  36. public int value() { return this.value; }
  37. }

2.列表

Propagation 含义
REQUIRED 支持当前事务, 如果不存在, 则创建一个新事务
SUPPORTS 支持当前事务, 如果不存在, 则以非事务方式执行
MANDATORY 支持当前事务, 如果不存在则抛出异常
REQUIRES_NEW 开始一个新的事务, 并暂停当前事务(如果存在)
NOT_SUPPORTED 以非事务方式执行, 暂停当前事务(如果存在)
NEVER 以非事务方式执行, 如果存在则抛出异常
NESTED 如果当前事务存在, 则在嵌套事务中执行. 如果事务不存在, 则等同于 PROPAGATION_REQUIRED

隔离级别介绍

1.枚举介绍

  1. package org.springframework.transaction.annotation;
  2. import org.springframework.transaction.TransactionDefinition;
  3. public enum Isolation {
  4. /**
  5. * 使用底层数据存储默认的隔离级别
  6. * 一般存储底层默认为: READ_COMMITTED
  7. */
  8. DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),
  9. /**
  10. * 读未提交
  11. * 会出现脏读和不可重复读, 一般不使用
  12. */
  13. READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
  14. /**
  15. * 读已提交
  16. * 该级别仅禁止事务读取其中未提交更改的行
  17. * 可能会出现不可重复读取和幻像读取
  18. */
  19. READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),
  20. /**
  21. * 可重复读
  22. * 禁止事务读取其中有未提交更改的行, 并且还禁止一个事务读取一行, 第二个事务更改该行. 并且第一个事务重新读取该行, 第二次获取不同值的情况
  23. * 即 禁止 读未提交, 不可重复读
  24. * 会出现幻读
  25. */
  26. REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),
  27. /**
  28. * 串行
  29. * 所有事物依次执行, 不会影响别的事务, 所以会防止 不可重复读 脏读 幻读
  30. * 会影响性能
  31. */
  32. SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
  33. private final int value;
  34. Isolation(int value) { this.value = value; }
  35. public int value() { return this.value; }
  36. }

2.列表

Isolation 含义
DEFAULT 使用底层数据存储默认的隔离级别, 一般存储底层默认为: READ_COMMITTED
READ_UNCOMMITTED 读未提交, 会出现脏读和不可重复读, 一般不使用
READ_COMMITTED 该级别仅禁止事务读取其中未提交更改的行. 可能会出现不可重复读取和幻像读取
REPEATABLE_READ 可重复读, 禁止事务读取其中有未提交更改的行, 并且还禁止一个事务读取一行, 第二个事务更改该行. 并且第一个事务重新读取该行, 第二次获取不同值的情况. 即 禁止 读未提交, 不可重复读. 会出现幻读
SERIALIZABLE 串行, 所有事物依次执行, 不会影响别的事务, 所以会防止 不可重复读 脏读 幻读. 会影响性能

3.脏读 幻读 不可重复读

脏读 当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
幻读 事务读取时不存在该数据, 读取后发现该数据存在. 中间因为别的事务在进行插入操作
不可重复读 一个事务在读取该数据时另一个事务在修改该数据, 导致多次读取数据内容不一致