Create two entity beans.
@Entity @Table(name="T_COMPANY") public class Company{ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; @Column(name = "NAME") private String name; public Company() { super(); } public Company(String name) { super(); this.name = name; } }
@Entity @Table(name="T_PERSON") public class Person{ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; @Column(name = "NAME") private String name; public Person() { super(); } public Person(String name) { super(); this.name = name; } }
Create a stateless session bean (companyBean) with a method having REQUIRES_NEW transaction attribute type.
@Stateless(name="companyBean") @Local(CompanyManager.class) public class CompanyManagerBean implements CompanyManager { @PersistenceContext(unitName="unit") private EntityManager em; @Override @TransactionAttribute (TransactionAttributeType.REQUIRES_NEW) public void save(Company company) { em.persist(company); } }
Create another stateless session bean (personBean), and inject the companyBean into the personBean.
@Stateless(name="personBean") @Local(PersonManager.class) public class PersonManagerBean implements PersonManager { @PersistenceContext(unitName="unit") private EntityManager em; @EJB(beanName="companyBean") private CompanyManager companyManager; @Override @TransactionAttribute (TransactionAttributeType.REQUIRED) public void save(Person person) { companyManager.save(new Company("Oracle")); em.persist(person); } }
Write a servlet to test
public class PersonServlet extends HttpServlet { @EJB(beanName="personBean") private PersonManager personManager = null; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { personManager.save(new Person("Mingtao001")); } }
Result:
Table T_COMPANY
Table T_PERSON
Now throw an exception in personBean
@Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void save(Person person) { companyManager.save(new Company("Oracle")); em.persist(person); throw new RuntimeException("error!"); }
Clean the table and retest the servlet
Result:
Table T_COMPANY
Table T_PERSON
The SQL that saves the person has been rolled back while the SQL that saves the company was not affected.
Now change the transaction attribute type from REQUIRES_NEW to REQUIRED in companyBean.
@Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void save(Company company) { em.persist(company); }
Clean the table and retest the servlet
Result:
Table T_COMPANY
Table T_PERSON
Both SQLs have been rolled back as they are in the same transaction.
No comments:
Post a Comment