spring(四)事务管理
原教程: https://www.w3cschool.cn/wkspring/
spring编程式事务管理
- org.springframework.transaction.PlatformTransactionManager 接口(提交或回滚事务)
- TransactionDefinition 接口(定义事务的隔离级别和事务传播行为)
- TransactionStatus 接口(查询事务的状态)
- 使用方式:
- TransactionDefinition def = new DefaultTransactionDefinition();
- TransactionStatus status = transactionManager.getTransaction(def);
- PlatformTransactionManager_Object.commit(status);
- PlatformTransactionManager_Object.rollback(status);
- beans.xml
- 配置数据源bean:org.springframework.jdbc.datasource.DriverManagerDataSource(初始化DateSource)
- 声明TransactionManager bean org.springframework.jdbc.datasource.DataSourceTransactionManager(初始化PlatformTransactionManager)
- 声明引用上面两个bean的bean
spring声明式事务管理
将事务管理从事务代码中隔离出来,使用注释或者配置XML文件来管理事务。
步骤:
- 使用<tx:advice>创建事务处理的Advice,指定需要作为事务的方法(目标方法)以及transaction-manager
- (这一步可有可无)声明切入点,expression中方法(目标方法)都是事务型的(符合ACID)
- 目标方法在try/catch块中执行
- 发生异常,事务回滚
最重要的是beans.xml文件的配置
1 // beans.xml 2 <?xml version="1.0" encoding="UTF-8"?> 3 <beans xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:aop="http://www.springframework.org/schema/aop" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 9 http://www.springframework.org/schema/tx 10 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> 13 14 <!-- Initialization for data source --> 15 <bean id="dataSource" 16 class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 17 <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 18 <property name="url" value="jdbc:mysql://localhost:3306/test"/> 19 <property name="username" value="root"/> 20 <property name="password" value="usbw"/> 21 </bean> 22 23 <tx:advice id="txAdvice" transaction-manager="transactionManager"> 24 <tx:attributes> 25 <tx:method name="create"/> 26 </tx:attributes> 27 </tx:advice> 28 29 <!-- <aop:config> --> 30 <!-- <aop:pointcut id="createOperation" --> 31 <!-- expression="execution(* com.springjdbc.StudentJDBCTemplate.create(..))"/> --> 32 <!-- <aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation"/> --> 33 <!-- </aop:config> --> 34 35 <!-- Initialization for TransactionManager --> 36 <bean id="transactionManager" 37 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 38 <property name="dataSource" ref="dataSource" /> 39 </bean> 40 41 <!-- Definition for studentJDBCTemplate bean --> 42 <bean id="studentJDBCTemplate" 43 class="com.springjdbc.StudentJDBCTemplate"> 44 <property name="dataSource" ref="dataSource" /> 45 </bean> 46 47 </beans> 48 49 //StudentDao.java 50 public interface StudentDao { 51 public void setDataSource(DataSource ds); 52 public void create(String name, Integer age, Integer marks, Integer year); 53 public List<StudentMarks> listStudent(); 54 } 55 56 // StudentMarks.java 57 public class StudentMarks { 58 private Integer age; 59 private String name; 60 private Integer id; 61 private Integer marks; 62 private Integer year; 63 private Integer sid; 64 public Integer getAge() { 65 return age; 66 } 67 public void setAge(Integer age) { 68 this.age = age; 69 } 70 public String getName() { 71 return name; 72 } 73 public void setName(String name) { 74 this.name = name; 75 } 76 public Integer getId() { 77 return id; 78 } 79 public void setId(Integer id) { 80 this.id = id; 81 } 82 public Integer getMarks() { 83 return marks; 84 } 85 public void setMarks(Integer marks) { 86 this.marks = marks; 87 } 88 public Integer getYear() { 89 return year; 90 } 91 public void setYear(Integer year) { 92 this.year = year; 93 } 94 public Integer getSid() { 95 return sid; 96 } 97 public void setSid(Integer sid) { 98 this.sid = sid; 99 } 100 } 101 102 // StudentMarksMapper.java 103 public class StudentMarksMapper implements RowMapper<StudentMarks>{ 104 105 @Override 106 public StudentMarks mapRow(ResultSet rs, int rowNum) throws SQLException { 107 StudentMarks studentMarks = new StudentMarks(); 108 studentMarks.setId(rs.getInt("id")); 109 studentMarks.setName(rs.getString("name")); 110 studentMarks.setAge(rs.getInt("age")); 111 studentMarks.setSid(rs.getInt("sid")); 112 studentMarks.setMarks(rs.getInt("marks")); 113 studentMarks.setYear(rs.getInt("year")); 114 return studentMarks; 115 } 116 } 117 118 // StudentJDBCTemplate.java 119 public class StudentJDBCTemplate implements StudentDao { 120 private JdbcTemplate jdbcTemplateObject; 121 public void setDataSource(DataSource ds) { 122 this.jdbcTemplateObject = new JdbcTemplate(ds); 123 } 124 @Override 125 public void create(String name, Integer age, Integer marks, Integer year) { 126 System.out.println("StudentJDBCTemplate create()"); 127 try { 128 String sql1 = "insert into student(name, age) values(?,?)"; 129 jdbcTemplateObject.update(sql1, name, age); 130 131 String sql3 = "insert into Marks(marks, year) values(?,?)"; 132 jdbcTemplateObject.update(sql3, marks, year); 133 System.out.println("created name = "+name+", age = "+age); 134 throw new RuntimeException("simulate Error condition"); 135 } catch (DataAccessException e) { 136 System.out.println("Error in creating record, rolling back"); 137 throw e; 138 } 139 } 140 @Override 141 public List<StudentMarks> listStudent() { 142 String sql = "select * from student, marks where student.id=marks.sid"; 143 List<StudentMarks> studentMarks = jdbcTemplateObject.query(sql, new StudentMarksMapper()); 144 return studentMarks; 145 } 146 } 147 148 // MainApp.java 149 public class MainApp { 150 public static void main(String[] args) { 151 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); 152 StudentDao studentJDBCTemplate = (StudentDao) context.getBean("studentJDBCTemplate"); 153 System.out.println("----------插入记录----------"); 154 studentJDBCTemplate.create("Zara", 11, 99, 2010); 155 studentJDBCTemplate.create("Nuha", 20, 97, 2010); 156 System.out.println("----------获取所有记录----------"); 157 List<StudentMarks> listStudent = studentJDBCTemplate.listStudent(); 158 for (StudentMarks record : listStudent) { 159 System.out.print("ID : " + record.getId() ); 160 System.out.print(", Name : " + record.getName() ); 161 System.out.print(", Marks : " + record.getMarks()); 162 System.out.print(", Year : " + record.getYear()); 163 System.out.println(", Age : " + record.getAge()); 164 } 165 } 166 }
运行结果: ----------插入记录---------- StudentJDBCTemplate create() created name = Zara, age = 11 Exception in thread "main" java.lang.RuntimeException: simulate Error condition