Spring单实例、多线程安全、事务解析
- - zzm 在使用Spring时,很多人可能对Spring中为什么DAO和Service对象采用单实例方式很迷惑,这些读者是这么认为的:. DAO对象必须包含一个数据库的连接Connection,而这个Connection不是线程安全的,所以每个DAO都要包含一个不同的Connection对象实例,这样一来DAO对象就不能是单实例的了.
public class SqlConnection { //①使用ThreadLocal保存Connection变量 privatestatic ThreadLocal <Connection>connThreadLocal = newThreadLocal<Connection>(); publicstatic Connection getConnection() { // ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection, // 并将其保存到线程本地变量中。 if (connThreadLocal.get() == null) { Connection conn = getConnection(); connThreadLocal.set(conn); return conn; } else { return connThreadLocal.get(); // ③直接返回线程本地变量 } } public voidaddTopic() { // ④从ThreadLocal中获取线程对应的Connection try { Statement stat = getConnection().createStatement(); } catch (SQLException e) { e.printStackTrace(); } } }
@Service( "userService") public class UserService extends BaseService { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private ScoreService scoreService; public void logon(String userName) { updateLastLogonTime(userName); scoreService.addScore(userName, 20); } public void updateLastLogonTime(String userName) { String sql = "UPDATE t_user u SET u.last_logon_time = ? WHERE user_name =?"; jdbcTemplate.update(sql, System. currentTimeMillis(), userName); } public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/nestcall/applicatonContext.xml" ); UserService service = (UserService) ctx.getBean("userService" ); service.logon( "tom"); } } @Service( "scoreUserService" ) public class ScoreService extends BaseService{ @Autowired private JdbcTemplate jdbcTemplate; public void addScore(String userName, int toAdd) { String sql = "UPDATE t_user u SET u.score = u.score + ? WHERE user_name =?"; jdbcTemplate.update(sql, toAdd, userName); } }
@Service( "userService") public class UserService extends BaseService { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private ScoreService scoreService; public void logon(String userName) { updateLastLogonTime(userName); Thread myThread = new MyThread(this.scoreService , userName, 20);//使用一个新线程运行 myThread .start(); } public void updateLastLogonTime(String userName) { String sql = "UPDATE t_user u SET u.last_logon_time = ? WHERE user_name =?"; jdbcTemplate.update(sql, System. currentTimeMillis(), userName); } private class MyThread extends Thread { private ScoreService scoreService; private String userName; private int toAdd; private MyThread(ScoreService scoreService, String userName, int toAdd) { this. scoreService = scoreService; this. userName = userName; this. toAdd = toAdd; } public void run() { scoreService.addScore( userName, toAdd); } } public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/multithread/applicatonContext.xml" ); UserService service = (UserService) ctx.getBean("userService" ); service.logon( "tom"); } }
@Service( "jdbcUserService" ) public class JdbcUserService { @Autowired private JdbcTemplate jdbcTemplate; @Transactional public void logon(String userName) { try { Connection conn = jdbcTemplate.getDataSource().getConnection(); String sql = "UPDATE t_user SET last_logon_time=? WHERE user_name =?"; jdbcTemplate.update(sql, System. currentTimeMillis(), userName); } catch (Exception e) { e.printStackTrace(); } } public static void asynchrLogon(JdbcUserService userService, String userName) { UserServiceRunner runner = new UserServiceRunner(userService, userName); runner.start(); } public static void reportConn(BasicDataSource basicDataSource) { System. out.println( "连接数[active:idle]-[" + basicDataSource.getNumActive()+":" +basicDataSource.getNumIdle()+ "]"); } private static class UserServiceRunner extends Thread { private JdbcUserService userService; private String userName; public UserServiceRunner(JdbcUserService userService, String userName) { this. userService = userService; this. userName = userName; } public void run() { userService.logon( userName); } } public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/connleak/applicatonContext.xml" ); JdbcUserService userService = (JdbcUserService) ctx.getBean("jdbcUserService" ); JdbcUserService. asynchrLogon(userService, "tom"); } }
http://www.xuebuyuan.com/1771946.html
http://www.oschina.net/question/87799_11230