Spring @Transactional使用的示例:
参考:
http://blog.csdn.net/seng3018/article/details/6690527
http://blog.sina.com.cn/s/blog_667ac0360102ebem.html
context.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <bean id="dbcpds" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property> <property name="url" value="jdbc:oracle:thin:@localhost:1521:ora11"></property> <property name="username" value="a"></property> <property name="password" value="b"></property> <property name="initialSize" value="5"></property> <property name="maxActive" value="10"></property> </bean> <bean id="jdbcSpitter2DAO" class="com.stono.sprjdbc.JdbcSpitter2Dao"> <property name="dataSource" ref="dbcpds"></property> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dbcpds"></property> </bean> <tx:annotation-driven transaction-manager="txManager" /> </beans>
POJO:
package com.stono.sprjdbc; public class SpitterObj { private String ljdm; private String ljpym; public String getLjdm() { return ljdm; } public void setLjdm(String ljdm) { this.ljdm = ljdm; } public String getLjpym() { return ljpym; } public void setLjpym(String ljpym) { this.ljpym = ljpym; } }
DAO:
package com.stono.sprjdbc; import java.util.Map; public interface SpitterDAO { void insertSpitter(SpitterObj obj); void namedInsertSpitter(Map<String, Object> map); void updateSpitter(SpitterObj obj); void deleteSpitter(SpitterObj obj); SpitterObj getSpitter(String ljdm); }
DAO Implements:
package com.stono.sprjdbc; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; public class JdbcSpitter2Dao extends NamedParameterJdbcDaoSupport implements SpitterDAO { private static String INSERT_SQL = "insert into ljzdtemp(ljdm,ljpym) values(?,?)"; private static String GET_SQL = "select * from ljzdtemp where ljdm = ?"; private static String UPDATE_SQL = "update ljzdtemp set ljpym=? where ljdm = ?"; private static String DEL_SQL = "delete ljzdtemp where ljdm = ?"; private static String NAMED_INSERT_SQL = "insert into ljzdtemp(ljdm,ljpym) values(:ljdm,:ljpym)"; @Override public void insertSpitter(SpitterObj obj) { getJdbcTemplate().update(INSERT_SQL, obj.getLjdm(), obj.getLjpym()); } // 如下设置会有异常:Exception in thread "main" org.springframework.transaction.IllegalTransactionStateException: No existing // transaction found for transaction marked with propagation 'mandatory' // @Transactional(propagation = Propagation.MANDATORY, readOnly = true, timeout = 1) // 如下进行设置,含有timeout=1的情况,代码中sleep2秒,会有异常: // Exception in thread "main" org.springframework.transaction.TransactionTimedOutException: Transaction timed out: // deadline was Sun Oct 25 08:44:43 CST 2015 // @Transactional(propagation = Propagation.REQUIRED, readOnly = true, timeout = 1) // try { // Thread.sleep(2000); // } catch (Exception e) { // e.printStackTrace(); // } // 如下设置,会有异常,并且会导致事务回滚,插入没有成功; // Exception in thread "main" java.lang.ArithmeticException: / by zero // @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class) // int i = 0, j = 1; // int k = 1 / i; // System.out.println(i + j + k); // 如下设置,同上面的情况也是一样的; // @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = ArithmeticException.class) // 如下设置,没有进行回滚设置,但是还是会回滚,因为有异常了; // @Transactional(propagation = Propagation.REQUIRED, readOnly = false) // int i = 0, j = 1; // int k = 1 / i; // System.out.println(i + j + k); // 如下设置,就不会发生回滚事件: // @Transactional(propagation = Propagation.REQUIRED, noRollbackFor = ArithmeticException.class) // int i = 0, j = 1; // int k = 1 / i; // System.out.println(i + j + k); @Override public void namedInsertSpitter(Map<String, Object> map) { getNamedParameterJdbcTemplate().update(NAMED_INSERT_SQL, map); } // 如果想用 Propagation.MANDATORY的方式,就在别的方法中调用这个方法,然后在别的方法中加上 Propagation.REQUIRED // namedInsertSpitter2(map); @Transactional(propagation = Propagation.MANDATORY) public void namedInsertSpitter2(Map<String, Object> map) { getNamedParameterJdbcTemplate().update(NAMED_INSERT_SQL, map); } @Override public void updateSpitter(SpitterObj obj) { getJdbcTemplate().update(UPDATE_SQL, "aa", "a"); } // 这样设置readOnly=true竟然没有效果; @Transactional(propagation = Propagation.REQUIRED, readOnly = true) @Override public void deleteSpitter(SpitterObj obj) { Map<String, Object> map = new HashMap<String, Object>(); map.put("ljdm", "d"); map.put("ljpym", "d"); getNamedParameterJdbcTemplate().update(NAMED_INSERT_SQL, map); getJdbcTemplate().update(DEL_SQL, "d"); getNamedParameterJdbcTemplate().update(NAMED_INSERT_SQL, map); getNamedParameterJdbcTemplate().update(NAMED_INSERT_SQL, map); } @Override public SpitterObj getSpitter(String ljdm) { return getJdbcTemplate().queryForObject(GET_SQL, new RowMapper<SpitterObj>() { @Override public SpitterObj mapRow(ResultSet rs, int rowNum) throws SQLException { SpitterObj obj = new SpitterObj(); obj.setLjdm(rs.getString(4)); obj.setLjpym(rs.getString(5)); return obj; } }, 'a'); } }
AppBean:
package com.stono.sprjdbc; import java.util.HashMap; import java.util.Map; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; public class AppBeans15 { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("appbeans15.xml"); // insert(context); // insertReadOnly(context); deleteSpitter(context); } @Transactional(propagation = Propagation.MANDATORY) private static void insert(ApplicationContext context) { SpitterDAO dao2 = (SpitterDAO) context.getBean("jdbcSpitter2DAO"); Map<String, Object> map = new HashMap<String, Object>(); map.put("ljdm", "d"); map.put("ljpym", "d"); dao2.namedInsertSpitter(map); } public static void insertReadOnly(ApplicationContext context) { SpitterDAO dao2 = (SpitterDAO) context.getBean("jdbcSpitter2DAO"); Map<String, Object> map = new HashMap<String, Object>(); map.put("ljdm", "d"); map.put("ljpym", "d"); dao2.namedInsertSpitter(map); } public static void deleteSpitter(ApplicationContext context) { SpitterDAO dao2 = (SpitterDAO) context.getBean("jdbcSpitter2DAO"); dao2.deleteSpitter(null); } }