编程式事务管理方法允许你在源代码编程的方式下管理事务。虽然带来了极大地灵活性,但是它很难维护。
实践前提:
1、在MySql新建Student,Marks两张表,脚本如下:
CREATE TABLEStudent(
IDINT NOT NULLAUTO_INCREMENT,
NAMEVARCHAR(20) NOT NULL,
AGEINT NOT NULL,PRIMARY KEY(ID)
);
CREATE TABLEMarks(
SIDINT NOT NULL,
MARKSINT NOT NULL,YEAR INT NOT NULL);
2、增加mysql-connector-java.jar包,POM配置如下:
mysql
mysql-connector-java
5.1.38
3、原理:
使用PlatformTransactionManager来实现编程式方法实现事务。要开始一个新事务,需要有一个带有适当的transaction属性的TransactionDefinition的实例。这里,我们使用默认的transaction属性创建DefaultTransactionDefinition的一个实例。当TransactionDefinition创建后,可以通过调用getTransaction()方法来开始事务,该方法会返回TransactionStatus的一个实例。TransactionStatus对象帮助追踪当前的事务状态,并且最终,如果一切运行顺利,你可以使用PlatformTransactionManager的commit()方法来提交这个事务,否则的话,你可以使用rollback()方法来回滚整个操作。
例子:
pom.xml:
4.0.0
com.jsoft.testspring
testtx
0.0.1-SNAPSHOT
jar
testtx
http://maven.apache.org
UTF-8
junit
junit
3.8.1
test
org.springframework
spring-core
4.1.4.RELEASE
org.springframework
spring-context
4.1.4.RELEASE
org.springframework
spring-jdbc
4.1.4.RELEASE
org.springframework
spring-tx
4.1.4.RELEASE
mysql
mysql-connector-java
5.1.38
StudentMarks.java:
packagecom.jsoft.testspring.testtx;public classStudentMarks {privateInteger age;privateString name;privateInteger id;privateInteger marks;privateInteger year;privateInteger sid;public voidsetAge(Integer age) {this.age =age;
}publicInteger getAge() {returnage;
}public voidsetName(String name) {this.name =name;
}publicString getName() {returnname;
}public voidsetId(Integer id) {this.id =id;
}publicInteger getId() {returnid;
}public voidsetMarks(Integer marks) {this.marks =marks;
}publicInteger getMarks() {returnmarks;
}public voidsetYear(Integer year) {this.year =year;
}publicInteger getYear() {returnyear;
}public voidsetSid(Integer sid) {this.sid =sid;
}publicInteger getSid() {returnsid;
}
}
StudentMarksMapper.java:
packagecom.jsoft.testspring.testtx;importjava.sql.ResultSet;importjava.sql.SQLException;importorg.springframework.jdbc.core.RowMapper;public class StudentMarksMapper implements RowMapper{
@Overridepublic StudentMarks mapRow(ResultSet rs, int arg1) throwsSQLException {//TODO Auto-generated method stub
StudentMarks student = newStudentMarks();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
student.setSid(rs.getInt("sid"));
student.setMarks(rs.getInt("marks"));
student.setYear(rs.getInt("year"));returnstudent;
}
}
StudentDAO.java:
packagecom.jsoft.testspring.testtx;importjava.util.List;importjavax.sql.DataSource;importorg.springframework.transaction.PlatformTransactionManager;public interfaceStudentDAO {public voidsetDataSource(DataSource ds);public void setTransactionManager(PlatformTransactionManager transactionManager);public voidcreate(String name, Integer age, Integer marks, Integer year);publicStudentMarks getStudent(Integer id);public ListlistStudents();public voiddelete(Integer id);public voidupdate(Integer id, String name, Integer age, Integer marks, Integer year);
}
StudentJDBCTemplate.java:
packagecom.jsoft.testspring.testtx;importjava.util.List;importjavax.sql.DataSource;importorg.springframework.dao.DataAccessException;importorg.springframework.jdbc.core.JdbcTemplate;importorg.springframework.transaction.PlatformTransactionManager;importorg.springframework.transaction.TransactionDefinition;importorg.springframework.transaction.TransactionStatus;importorg.springframework.transaction.support.DefaultTransactionDefinition;public class StudentJDBCTemplate implementsStudentDAO {privateDataSource dataSource;privateJdbcTemplate jdbcTemplateObject;privatePlatformTransactionManager transactionManager;
@Overridepublic voidsetDataSource(DataSource dataSource) {this.dataSource =dataSource;this.jdbcTemplateObject = newJdbcTemplate(dataSource);
}
@Overridepublic void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager =transactionManager;
}
@Overridepublic voidcreate(String name, Integer age, Integer marks, Integer year) {
TransactionDefinition def= new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);try{
String SQL1= "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update( SQL1, name, age);
String SQL2= "select max(id) from Student";int sid =jdbcTemplateObject.queryForInt( SQL2 );
String SQL3= "insert into Marks(sid, marks, year) values (?, ?, ?)";
jdbcTemplateObject.update( SQL3, sid, marks, year);
System.out.println("Created Name = " + name + ", Age = " +age);
transactionManager.commit(status);
}catch(DataAccessException e) {
System.out.println("Error in creating record, rolling back");
transactionManager.rollback(status);throwe;
}return;
}
@OverridepublicStudentMarks getStudent(Integer id) {
String SQL= "select * from Student,Marks where id = ? and Student.id=Marks.sid";
StudentMarks student= jdbcTemplateObject.queryForObject(SQL, new Object[] { id }, newStudentMarksMapper());returnstudent;
}
@Overridepublic ListlistStudents() {
String SQL= "select * from Student,Marks where Student.id = Marks.sid";
List students = jdbcTemplateObject.query(SQL, newStudentMarksMapper());returnstudents;
}
@Overridepublic voiddelete(Integer id) {
TransactionDefinition def= new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);try{
String SQL1= "delete from Student where id = ?";
jdbcTemplateObject.update(SQL1, id);
System.out.println("Deleted Record with ID = " +id);
String SQL2= "delete from Marks where sid = ?";
jdbcTemplateObject.update(SQL2, id);
System.out.println("Deleted Record with SID = " +id);
transactionManager.commit(status);
}catch(DataAccessException e) {
System.out.println("Error in creating record, rolling back");
transactionManager.rollback(status);throwe;
}return;
}
@Overridepublic voidupdate(Integer id, String name, Integer age, Integer marks, Integer year) {
TransactionDefinition def= new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);try{
String SQL1= "update Student set age = ?,name = ? where id = ?";
jdbcTemplateObject.update(SQL1, age,name, id);
System.out.println("Updated Record with ID = " +id);
String SQL2= "update Marks set marks = ?,year = ? where sid = ?";
jdbcTemplateObject.update(SQL2, marks,year, id);
System.out.println("Updated Record with SID = " +id);
transactionManager.commit(status);
}catch(DataAccessException e) {
System.out.println("Error in creating record, rolling back");
transactionManager.rollback(status);throwe;
}return;
}
}
beans.xml:
http://www.springframework.org/schema/beans/spring-beans.xsd">
测试结果: