分类存档: hibernate

hibernate mysql autocommit(二)

查看 上一篇hibernate性能优化:

hibernate mysql autocommit : http://blog.zhukunqian.com/?p=162

本次要解决 mysql jdbc driver中的  SET autocommit=1 的问题.

驱动中默认是每次事务开启前

SET autocommit=0,

事务开始

事务结束

set autocommit=1,

可以看到以上流程中的set autocommit=1是完全没有毕要,而且会影响到数据库性能.更为重要的是,这完全是硬编码在驱动中的,所以我们无法使用设置参数来试图取消autocommit.

mysql jdbc driver 5.1.6 版中提供了com.mysql.jdbc.ConnectionLifecycleInterceptor,使我们可以利用interceptor的机制来控制mysql中的事务流程.

以下是一个样例:

package game.joycube.common.util.jdbc;

import java.sql.SQLException;
import java.sql.Savepoint;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.mysql.jdbc.Connection;

public class ConnectionLifecycleInterceptor implements
com.mysql.jdbc.ConnectionLifecycleInterceptor {

private static final Log log = LogFactory
.getLog(ConnectionLifecycleInterceptor.class);

public void close() throws SQLException {
log.info(“close”);
}

public boolean commit() throws SQLException {
log.info(“commit”);
return true;
}

public boolean rollback() throws SQLException {
log.info(“rollback”);
// 这里的rollback,没有设置savepoint,应该每次都不rollback
return false;
}

public boolean rollback(Savepoint arg0) throws SQLException {
log.info(“rollback savepoint ” + arg0);
// 设置了savepoint,应该rollback
return true;
}

public boolean setAutoCommit(boolean arg0) throws SQLException {
log.info(“setAutoCommit ” + arg0);
// 如果要设置 set autoCommit=false,允许
// 如果要设置 set autoCommit=true,不允许
if (!arg0) {
return true;
}
return false;
}

public boolean setCatalog(String arg0) throws SQLException {
log.info(“setCatalog ” + arg0);
return true;
}

public boolean transactionBegun() throws SQLException {
log.info(“transactionBegun”);
return true;
}

public boolean transactionCompleted() throws SQLException {
log.info(“transactionCompleted”);
return true;
}

public void destroy() {
log.info(“destroy”);
}

public void init(Connection arg0, Properties arg1) throws SQLException {
log.info(“ConnectionLifecycleInterceptor init ” + arg0 + “\t” + arg1);
}
}

以上接口中返回boolean中,true表示按驱动原逻辑执行,false表示驱动不执行此次操作

public boolean setAutoCommit(boolean arg0) throws SQLException {
log.info(“setAutoCommit ” + arg0);
// 如果要设置 set autoCommit=false,允许
// 如果要设置 set autoCommit=true,不允许
if (!arg0) {
return true;
}
return false;
}

这段代码含义为:

当驱动要执行:set autocommit=0时,

arg0为false,这里返回true,驱动按原逻辑执行

当执行set autocomit=1时

arg0为true,这里返回false,禁止驱动执行本次操作

OK,代码准备好后,我们在驱动中启用此interceptor

jdbc:mysql://127.0.0.1/wgame?connectionLifecycleInterceptors=game.joycube.common.util.jdbc.ConnectionLifecycleInterceptor

这样就启用了此interceptor.

如果 启用后无法生效,请检查一下jdbc驱动的版本,(版本:5.1.6 +)
参考:http://www.jroller.com/mmatthews/entry/huh_i_didn_t_know

 

hibernate mysql autocommit

http://forum.springsource.org/showthread.php?12639-MySQL-set-autocommit-0-set-autocommit-1

以下设置避免每次事务都向db发送无用的commit请求

<bean id="dataSourceTarget">
  <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
  <property name="url"><value>jdbc&#58;mysql&#58;//localhost&#58;3306/imagedb</value></property>
  <property name="username"><value>admin</value></property>
  <property name="password"><value></value></property>
</bean>

<bean id="dataSource">
  <property name="targetDataSource"><ref local="dataSource"/></property>
</bean>

设置之前:

__ Questions ___________________________________________________________
Total           1.88M     5.3/s
Com_          1.32M     3.7/s  %Total:  69.98
DMS         512.62k     1.5/s           27.28
QC Hits      51.53k     0.1/s            2.74
COM_QUIT         36     0.0/s            0.00
-Unknown          7     0.0/s            0.00
Slow 2 s            2     0.0/s            0.00  %DMS:   0.00  Log:  ON
DMS           512.62k     1.5/s           27.28
SELECT      373.42k     1.1/s           19.87         72.85
INSERT       68.29k     0.2/s            3.63         13.32
UPDATE       61.07k     0.2/s            3.25         11.91
DELETE        9.84k     0.0/s            0.52          1.92
REPLACE           0       0/s            0.00          0.00
Com_            1.32M     3.7/s           69.98
set_option  875.44k     2.5/s           46.59
commit      436.17k     1.2/s           23.21
change_db       544     0.0/s            0.03

 

设置之后:

__ Questions ___________________________________________________________
Total          50.41M   197.8/s
DMS          32.99M   129.5/s  %Total:  65.45
Com_         16.53M    64.9/s           32.78
QC Hits     855.49k     3.4/s            1.70
COM_QUIT     34.27k     0.1/s            0.07
-Unknown         29     0.0/s            0.00
Slow 2 s            1     0.0/s            0.00  %DMS:   0.00  Log:  ON
DMS            32.99M   129.5/s           65.45
SELECT       17.61M    69.1/s           34.94         53.38
UPDATE       11.46M    45.0/s           22.74         34.74
INSERT        3.38M    13.3/s            6.70         10.24
DELETE      544.37k     2.1/s            1.08          1.65
REPLACE           0       0/s            0.00          0.00
Com_           16.53M    64.9/s           32.78
set_option   10.99M    43.1/s           21.81
commit        5.43M    21.3/s           10.76
change_db    34.37k     0.1/s            0.07
可以看到在设置之后

DMS语句从比例27%提升至65%.性能提升非常大.

 

hibernate onetoone与ehcache

双向OneToOne关联不要设置mappedBy,不然无法利用以ehcache.

正确的做法应该是OneToOne设置为双向关联,这样可以利用ehcache.