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