【数据库】使用Collection.setAutoCommit(false)的注意事项
2017-05-23 13:38
531 查看
setAutoCommit总的来说就是保持数据的完整性,一个系统的更新操作可能要涉及多张表,需多个SQL语句进行操作
循环里连续的进行插入操作,如果你在开始时设置了:conn.setAutoCommit(false);
最后才进行conn.commit(),这样你即使插入的时候报错,修改的内容也不会提交到数据库,
而如果你没有手动的进行setAutoCommit(false);
出错时就会造成,前几条插入,后几条没有
会形成脏数据~~
setAutoCommit(false)的误用
(设定setAutoCommit(false)没有在catch中进行Connection的rollBack操作,操作的表就会被锁住,造成数据库死锁):
误用Connection.setAutoCommit导致的数据库死锁问题。
系统在发布到用户的的服务器了,运行一段时间偶尔出现某些功能不能正常运行,甚至不能自动恢复,严重导致服务器当机,表现为服务器不响应用户的请求,数据库有大量的锁。在服务器重启后才能恢复正常。今天通遍的查看了一下代码,初步分析了原因,记录了下来,跟大家交流交流。
先看下面一段有问题的代码:
1 Connection con = null;
2 try{
3 con = getConnection();
4 con.setAutoCommit(false);
/*
5 * update USER set name=’winson’ where id=’000001’;
*/
6 con.commit();
7 }finally{
8 if(con!=null){
9 try {
10 con.close();
11 } catch (SQLException e) {
12 e.printStackTrace();
13 }
}
}
分析:问题就出现在第4行,写代码的人把数据库连接con 设置成非自动提交,但没有在执行出现异常的时候进行回滚。如果在执行第5行的时候出现异常,con既没有提交也没有回滚,表USER就会被锁住(如果oracle数据库就是行锁),而这个锁却没有机会释放。有人会质疑,在执行con.close()的时候不会释放锁吗?因为如果应用服务器使用了数据库连接池,连接不会被断开。
附:在oracle上查看锁的方法:select * from v$lock_object或者select * from v$lock.
参考正确的写法应该是:
Connection con = null;
try{
con = getConnection();
con.setAutoCommit(false);
/*
* do what you want here.
*/
con.commit();
}catch(Throwable e){
if(con!=null){
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
throw new RuntimeException(e);
}finally{
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
这种疏忽很容易出现,但又导致非常严重的运行问题。所以在这里作个提醒,以后在处理外部资源的时候一定要格外小心。今天还发现代码中一些地方滥用synchronized关键字,导致系统性能受到很大的影响,处理不当跟前面提到问题一起出现,那系统就是时候over了。
循环里连续的进行插入操作,如果你在开始时设置了:conn.setAutoCommit(false);
最后才进行conn.commit(),这样你即使插入的时候报错,修改的内容也不会提交到数据库,
而如果你没有手动的进行setAutoCommit(false);
出错时就会造成,前几条插入,后几条没有
会形成脏数据~~
setAutoCommit(false)的误用
(设定setAutoCommit(false)没有在catch中进行Connection的rollBack操作,操作的表就会被锁住,造成数据库死锁):
误用Connection.setAutoCommit导致的数据库死锁问题。
系统在发布到用户的的服务器了,运行一段时间偶尔出现某些功能不能正常运行,甚至不能自动恢复,严重导致服务器当机,表现为服务器不响应用户的请求,数据库有大量的锁。在服务器重启后才能恢复正常。今天通遍的查看了一下代码,初步分析了原因,记录了下来,跟大家交流交流。
先看下面一段有问题的代码:
1 Connection con = null;
2 try{
3 con = getConnection();
4 con.setAutoCommit(false);
/*
5 * update USER set name=’winson’ where id=’000001’;
*/
6 con.commit();
7 }finally{
8 if(con!=null){
9 try {
10 con.close();
11 } catch (SQLException e) {
12 e.printStackTrace();
13 }
}
}
分析:问题就出现在第4行,写代码的人把数据库连接con 设置成非自动提交,但没有在执行出现异常的时候进行回滚。如果在执行第5行的时候出现异常,con既没有提交也没有回滚,表USER就会被锁住(如果oracle数据库就是行锁),而这个锁却没有机会释放。有人会质疑,在执行con.close()的时候不会释放锁吗?因为如果应用服务器使用了数据库连接池,连接不会被断开。
附:在oracle上查看锁的方法:select * from v$lock_object或者select * from v$lock.
参考正确的写法应该是:
Connection con = null;
try{
con = getConnection();
con.setAutoCommit(false);
/*
* do what you want here.
*/
con.commit();
}catch(Throwable e){
if(con!=null){
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
throw new RuntimeException(e);
}finally{
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
这种疏忽很容易出现,但又导致非常严重的运行问题。所以在这里作个提醒,以后在处理外部资源的时候一定要格外小心。今天还发现代码中一些地方滥用synchronized关键字,导致系统性能受到很大的影响,处理不当跟前面提到问题一起出现,那系统就是时候over了。
相关文章推荐
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项(转)
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Connection.setAutoCommit使用的注意事项
- Java Connection.setAutoCommit使用的注意事项
- setAutoCommit(false); 后没有手动commit. 对数据库有什么影响?
- connection.setAutoCommit注意事项
- 由于没有正确使用Connection.setAutoCommit(false)而导致SQL语句没有被提交
- Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())
- Windows Phone - 使用Sterling数据库几个注意事项
- SE_queryinfo_set_where_clause和SE_queryinfo_set_dynamic_bind使用注意事项
- VFP中set filter to 的使用注意事项