<version>
package entity;
import java.util.HashSet;
import java.util.Set;
public class Student
{
private String id;
private String cardId;
private int age;
private String name;
//版本控制
private int version;
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public Student()
{
}
public Student(String name, int age)
{
this.age = age;
this.name = name;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getCardId()
{
return cardId;
}
public void setCardId(String cardId)
{
this.cardId = cardId;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Student" table="student">
<id name="id" column="id" type="string">
<generator class="uuid"></generator>
</id>
<version name="version" column="version" type="integer"></version>
<property name="name" column="name" type="string"></property>
<property name="cardId" column="cardId" type="string"></property>
<property name="age" column="age" type="int"></property>
</class>
</hibernate-mapping>
package entity;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
/*
create table student (
id varchar(255) not null,
version integer not null,
name varchar(255),
cardId varchar(255),
age integer,
primary key (id)
)
*/
public class CreateTable
{
public static void main(String[] args)
{
SchemaExport export = new SchemaExport(new Configuration().configure());
export.create(true, true);
}
}
package entity;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class HibernateTest {
public static void main(String[] args) {
test2 ();
}
public static void test () {
Session session = HibernateUtil.getSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Student student = new Student ();
student.setCardId("123456");
student.setAge(40);
student.setName("zhangsan");
session.save(student);
tx.commit();
}catch(Exception ex) {
ex.printStackTrace();
if (null != tx) {
tx.rollback();
}
}finally {
session.close();
}
}
/*//类比版本控制系统cvs
* Hibernate:
select
student0_.id as id0_,
student0_.version as version0_,
student0_.name as name0_,
student0_.cardId as cardId0_,
student0_.age as age0_
from
student student0_
where
student0_.name=?
Hibernate:
select
student0_.id as id0_,
student0_.version as version0_,
student0_.name as name0_,
student0_.cardId as cardId0_,
student0_.age as age0_
from
student student0_
where
student0_.name=?
1
1
Hibernate:
update
student
set
version=?,
name=?,
cardId=?,
age=?
where
id=?
and version=?
2
1
Hibernate:
update
student
set
version=?,
name=?,
cardId=?,
age=?
where
id=?
and version=?
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [entity.Student#8a68abb33ef87973013ef87975a70001]
*
*/
public static void test2 () {
Session session1 = HibernateUtil.getSession();
Session session2 = HibernateUtil.getSession();
Transaction tx = null;
try {
Student student1 = (Student)session1.createQuery("from Student s where s.name = :name").setString("name", "lisi").uniqueResult();
Student student2 = (Student)session2.createQuery("from Student s where s.name = :name").setString("name", "lisi").uniqueResult();
System.out.println(student1.getVersion());
System.out.println(student2.getVersion());
Transaction tx1 = session1.beginTransaction();
student1.setName("zhangsan");
tx1.commit();
System.out.println(student1.getVersion());
System.out.println(student2.getVersion());
Transaction tx2 = session2.beginTransaction();
student2.setName("wangwu");
tx2.commit();
}catch(Exception ex) {
ex.printStackTrace();
if (null != tx) {
tx.rollback();
}
}finally {
session1.close();
session2.close();
}
}
}
timestamp:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Student" table="student">
<id name="id" column="id" type="string">
<generator class="uuid"></generator>
</id>
<timestamp name="lastDate" column = "lastDate"></timestamp>
<property name="name" column="name" type="string"></property>
<property name="cardId" column="cardId" type="string"></property>
<property name="age" column="age" type="int"></property>
</class>
</hibernate-mapping>
package entity;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Student
{
private String id;
private String cardId;
private int age;
private String name;
private Date lastDate;
public Date getLastDate() {
return lastDate;
}
public void setLastDate(Date lastDate) {
this.lastDate = lastDate;
}
public Student()
{
}
public Student(String name, int age)
{
this.age = age;
this.name = name;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getCardId()
{
return cardId;
}
public void setCardId(String cardId)
{
this.cardId = cardId;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
}
package entity;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
/*
create table student (
id varchar(255) not null,
lastDate datetime not null,
name varchar(255),
cardId varchar(255),
age integer,
primary key (id)
)
*/
public class CreateTable
{
public static void main(String[] args)
{
SchemaExport export = new SchemaExport(new Configuration().configure());
export.create(true, true);
}
}
package entity;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class HibernateTest {
public static void main(String[] args) {
test2();
}
public static void test () {
Session session = HibernateUtil.getSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Student student = new Student ();
student.setCardId("123456");
student.setAge(40);
student.setName("zhangsan");
session.save(student);
tx.commit();
}catch(Exception ex) {
ex.printStackTrace();
if (null != tx) {
tx.rollback();
}
}finally {
session.close();
}
}
/*//类比版本控制系统cvs 模拟二个并发的线程
Hibernate:
select
student0_.id as id0_,
student0_.lastDate as lastDate0_,
student0_.name as name0_,
student0_.cardId as cardId0_,
student0_.age as age0_
from
student student0_
where
student0_.name=?
Hibernate:
select
student0_.id as id0_,
student0_.lastDate as lastDate0_,
student0_.name as name0_,
student0_.cardId as cardId0_,
student0_.age as age0_
from
student student0_
where
student0_.name=?
2013-05-31 11:15:47.0
2013-05-31 11:15:47.0
Hibernate:
update
student
set
lastDate=?,
name=?,
cardId=?,
age=?
where
id=?
and lastDate=?
2013-05-31 11:17:59.437
2013-05-31 11:15:47.0
Hibernate:
update
student
set
lastDate=?,
name=?,
cardId=?,
age=?
where
id=?
and lastDate=?
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
*/
public static void test2 () {
Session session1 = HibernateUtil.getSession();
Session session2 = HibernateUtil.getSession();
Transaction tx = null;
try {
Student student1 = (Student)session1.createQuery("from Student s where s.name = :name").setString("name", "zhangsan").uniqueResult();
Student student2 = (Student)session2.createQuery("from Student s where s.name = :name").setString("name", "zhangsan").uniqueResult();
System.out.println(student1.getLastDate());
System.out.println(student2.getLastDate());
Transaction tx1 = session1.beginTransaction();
student1.setName("lisi");
tx1.commit();
System.out.println(student1.getLastDate());
System.out.println(student2.getLastDate());
Transaction tx2 = session2.beginTransaction();
student2.setName("wangwu");
tx2.commit();
}catch(Exception ex) {
ex.printStackTrace();
if (null != tx) {
tx.rollback();
}
}finally {
session1.close();
session2.close();
}
}
}
在应用程序中应该捕获该异常,这种异常有二种处理方式:
-方式一:自动的撤销事务,通知用户账号的信息已被其他事务修改,需要重新开始事务。
-方式二:通知用户账号信息已被其他事务修改,显示最新存款余额信息,由用户决定如何继续事务,用户也可以决定立刻撤销事务。
try {
tx = session.beginTransaction();
log.write("transferCheck():开始事务");
Thread.sleep(500);
Account account=(Account)session.get(Account.class,new Long(1));
log.write("transferCheck():查询到存款余额为:balance="+account.getBalance());
Thread.sleep(500);
account.setBalance(account.getBalance()+100);
log.write("transferCheck():汇入100元,把存款余额改为:"+account.getBalance());
tx.commit(); //当Hibernate执行update语句时,可能会抛出StaleObjectException
log.write("transferCheck():提交事务");
Thread.sleep(500);
}catch(StaleObjectStateException e){
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
System.out.println("账户信息已被其他事务修改,本事务被撤销,请重新开始支票转账事务");
log.write("transferCheck():账户信息已被其他事务修改,本事务被撤销");
}
利用乐观锁来协调并发的取款事务和支票转账服务