最近在研究spring整合hibernate的时候,spring里面的transaction默认是对RumtimeException进行自动回滚,但是验证了好几遍,依然能插入数据,然后查了一下资料,原来是跟mysql数据表的类型相关,不懂数据表类型的可以参考这篇文章:http://blog.chinaunix.net/uid-10064369-id-2971161.html
最关键的也就是创建表的时候设置表的数据类型为INNODB,例如:
CREATE TABLE t_log(
id INT AUTO_INCREMENT PRIMARY KEY,
msg VARCHAR(20)
)ENGINE = INNODB; //mysql默认的类型是:MyISAM
model层的代码我就不贴上来了
单元测试:
package com.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.model.User;
import com.service.Service;
public class Test {
@org.junit.Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
Service s = (Service) ac.getBean("service");
s.doCreate(new User());
}
}
service层:
package com.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.dao.ILogDAO;
import com.dao.IUserDAO;
import com.model.Log;
import com.model.User;
@Component("service")
public class Service {
private IUserDAO iud;
private ILogDAO ild;
public IUserDAO getIud() {
return iud;
}
@Resource(name="u")
public void setIud(IUserDAO iud) {
this.iud = iud;
}
@Transactional
public void doCreate(User u) {
this.iud.doCreate(u);
Log log = new Log();
log.setMsg("a user" + u.getName() + " save!");
this.ild.save(log);
}
public ILogDAO getIld() {
return ild;
}
@Resource(name="log")
public void setIld(ILogDAO ild) {
this.ild = ild;
}
}
UserDAOImpl:
package com.dao.impl;
import javax.annotation.Resource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component;
import com.dao.IUserDAO;
import com.model.Log;
import com.model.User;
@Component("u")
public class UserDAOImpl implements IUserDAO {
private SessionFactory sf;
@Override
public void doCreate(User u) {
Session session = this.sf.getCurrentSession();
// session.beginTransaction();
u.setName("小njj");
session.save(u);
// session.getTransaction().commit();
// session.close();
//用了spring声明式事务管理就不用注释的三句了
// throw new RuntimeException("error");
}
public SessionFactory getSf() {
return sf;
}
@Resource(name="sessionFactory")
public void setSf(SessionFactory sf) {
this.sf = sf;
}
}
LogDAOImlp:
package com.dao.impl;
import javax.annotation.Resource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component;
import com.dao.ILogDAO;
import com.model.Log;
import com.model.User;
@Component("log")
public class LogDAOImpl implements ILogDAO {
private SessionFactory sf;
@Override
public void save(Log log) {
Session session = this.sf.getCurrentSession();
session.save(log);
throw new RuntimeException("ddd");
//这里抛出了RuntimeException异常,会自动回滚,所以表没有数据插入
}
public SessionFactory getSf() {
return sf;
}
@Resource(name="sessionFactory")
public void setSf(SessionFactory sf) {
this.sf = sf;
}
}
创建表的时候有可能出现一些错误:
(1) ERROR 1005: Can’t create table xxx.frm(errno: 121)
* 1、表名重复
2、以该名字命名的表之前创建过后来删除了,但是对应的.frm文件还留在磁盘上
3、主键名字在全数据库范围内不是唯一的
解决方法:用sql语句删除数据库(不能用手工)或者直接改表名(为什么不删除.frm文件呢?小编试过在mysql里面的data文件夹删除.frm文件,以及整个文件夹都不成功,最后就删除数据库)
(2) The ‘InnoDB’ feature is disabled; you need MySQL built with ‘InnoDB’ to have
修改mysql里面的my.ini文件,在skip-innodb前面加#,表示开启