Hibernate example source code file (transactions.po)
This example Hibernate source code file (transactions.po) is included in the DevDaily.com
"Java Source Code
Warehouse " project. The intent of this project is to help you "Learn Java by Example " TM .
The Hibernate transactions.po source code
# translation of Collection_Mapping.po to
# Xi Huang <xhuang@redhat.com>, 2006.
# Xi HUANG <xhuang@redhat.com>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: Collection_Mapping\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2010-02-11T05:38:16\n"
"PO-Revision-Date: 2010-03-16 09:58+1000\n"
"Last-Translator: Xi HUANG <xhuang@redhat.com>\n"
"Language-Team: <en@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
#. Tag: title
#, no-c-format
msgid "Transactions and Concurrency"
msgstr "äº‹åŠ¡å’Œå¹¶å‘ "
#. Tag: para
#, no-c-format
msgid "The most important point about Hibernate and concurrency control is that it is easy to understand. Hibernate directly uses JDBC connections and JTA resources without adding any additional locking behavior. It is recommended that you spend some time with the JDBC, ANSI, and transaction isolation specification of your database management system."
msgstr "Hibernate 的事务和并å‘控制很容易掌æ¡ã€‚Hibernate 直接使用 JDBC 连接和 JTA 资æºï¼Œä¸æ·»åŠ ä»»ä½•é™„åŠ é”定行为。我们强烈推èä½ èŠ±ç‚¹æ—¶é—´äº†è§£ JDBC 编程,ANSI SQL 查询è¯è¨€å’Œä½ 使用的数æ®åº“系统的事务隔离规范。 "
#. Tag: para
#, no-c-format
msgid "Hibernate does not lock objects in memory. Your application can expect the behavior as defined by the isolation level of your database transactions. Through <literal>Session, which is also a transaction-scoped cache, Hibernate provides repeatable reads for lookup by identifier and entity queries and not reporting queries that return scalar values."
msgstr "Hibernate ä¸é”定内å˜ä¸çš„å¯¹è±¡ã€‚ä½ çš„åº”ç”¨ç¨‹åºä¼šæŒ‰ç…§ä½ çš„æ•°æ®åº“äº‹åŠ¡çš„éš”ç¦»çº§åˆ«è§„å®šçš„é‚£æ ·è¿ä½œã€‚幸äºæœ‰äº† <literal>Session,使得 Hibernate é€šè¿‡æ ‡è¯†ç¬¦æŸ¥æ‰¾ï¼Œå’Œå®žä½“æŸ¥è¯¢ï¼ˆä¸æ˜¯è¿”å›žæ ‡é‡å€¼çš„报表查询)æ供了å¯é‡å¤çš„读å–(Repeatable reads)功能,Session åŒæ—¶ä¹Ÿæ˜¯äº‹åŠ¡èŒƒå›´å†…的缓å˜ï¼ˆcache)。 "
#. Tag: para
#, no-c-format
msgid "In addition to versioning for automatic optimistic concurrency control, Hibernate also offers, using the <literal>SELECT FOR UPDATE syntax, a (minor) API for pessimistic locking of rows. Optimistic concurrency control and this API are discussed later in this chapter."
msgstr "除了对自动ä¹è§‚并å‘控制æ供版本管ç†ï¼Œé’ˆå¯¹è¡Œçº§æ‚²è§‚é”定,Hibernate 也æ供了辅助的(较å°çš„)API,它使用了 <literal>SELECT FOR UPDATE çš„ SQL è¯æ³•ã€‚æœ¬ç« åŽé¢ä¼šè®¨è®ºä¹è§‚并å‘控制和这个API。 "
#. Tag: para
#, no-c-format
msgid "The discussion of concurrency control in Hibernate begins with the granularity of <literal>Configuration, SessionFactory , and Session , as well as database transactions and long conversations."
msgstr "我们从 <literal>Configuration层ã€SessionFactory 层,和 Session 层开始讨论 Hibernate 的并行控制ã€æ•°æ®åº“事务和应用程åºçš„长事务。 "
#. Tag: title
#, no-c-format
msgid "Session and transaction scopes"
msgstr "Session 和事务范围(transaction scope)"
#. Tag: para
#, no-c-format
msgid "A <literal>SessionFactory is an expensive-to-create, threadsafe object, intended to be shared by all application threads. It is created once, usually on application startup, from a Configuration instance."
msgstr "<literal>SessionFactory 对象的创建代价很昂贵,它是线程安全的对象,它为所有的应用程åºçº¿ç¨‹æ‰€å…±äº«ã€‚它åªåˆ›å»ºä¸€æ¬¡ï¼Œé€šå¸¸æ˜¯åœ¨åº”用程åºå¯åŠ¨çš„时候,由一个 Configuraion 的实例æ¥åˆ›å»ºã€‚ "
#. Tag: para
#, no-c-format
msgid "A <literal>Session is an inexpensive, non-threadsafe object that should be used once and then discarded for: a single request, a conversation or a single unit of work. A Session will not obtain a JDBC Connection , or a Datasource , unless it is needed. It will not consume any resources until used."
msgstr "<literal>Session 对象的创建代价比较å°ï¼Œæ˜¯éžçº¿ç¨‹å®‰å…¨çš„,对于å•ä¸ªè¯·æ±‚,å•ä¸ªä¼šè¯ã€å•ä¸ªçš„ 工作å•å…ƒè€Œè¨€ï¼Œå®ƒåªè¢«ä½¿ç”¨ä¸€æ¬¡ï¼Œç„¶åŽå°±ä¸¢å¼ƒã€‚åªæœ‰åœ¨éœ€è¦çš„时候,一个 Session 对象 æ‰ä¼šèŽ·å–一个 JDBC çš„ Connection (或一个Datasource ï¼‰å¯¹è±¡ï¼Œå› æ¤å‡è‹¥ä¸ä½¿ç”¨çš„时候它ä¸æ¶ˆè´¹ä»»ä½•èµ„æºã€‚ "
#. Tag: para
#, no-c-format
msgid "In order to reduce lock contention in the database, a database transaction has to be as short as possible. Long database transactions will prevent your application from scaling to a highly concurrent load. It is not recommended that you hold a database transaction open during user think time until the unit of work is complete."
msgstr "æ¤å¤–我们还è¦è€ƒè™‘æ•°æ®åº“事务。数æ®åº“事务应该尽å¯èƒ½çš„çŸï¼Œé™ä½Žæ•°æ®åº“ä¸çš„é”争用。数æ®åº“长事务会阻æ¢ä½ 的应用程åºæ‰©å±•åˆ°é«˜çš„并å‘è´Ÿè½½ã€‚å› æ¤ï¼Œå‡è‹¥åœ¨ç”¨æˆ·æ€è€ƒæœŸé—´è®©æ•°æ®åº“事务开ç€ï¼Œç›´åˆ°æ•´ä¸ªå·¥ä½œå•å…ƒå®Œæˆæ‰å…³é—这个事务,这ç»ä¸æ˜¯ä¸€ä¸ªå¥½çš„设计。 "
#. Tag: para
#, no-c-format
msgid "What is the scope of a unit of work? Can a single Hibernate <literal>Session span several database transactions, or is this a one-to-one relationship of scopes? When should you open and close a Session and how do you demarcate the database transaction boundaries? These questions are addressed in the following sections."
msgstr "一个æ“作å•å…ƒï¼ˆUnit of work)的范围是多大?å•ä¸ªçš„ Hibernate <literal>Session 能跨越多个数æ®åº“事务å—?还是一个 Session 的作用范围对应一个数æ®åº“事务的范围?应该何时打开 Session ï¼Œä½•æ—¶å…³é— Session ï¼Œä½ åˆå¦‚何划分数æ®åº“事务的边界呢?我们将在åŽç»ç« 节解决这些问题。"
#. Tag: title
#, no-c-format
msgid "Unit of work"
msgstr "æ“作å•å…ƒï¼ˆUnit of work)"
#. Tag: para
#, no-c-format
msgid "First, let's define a unit of work. A unit of work is a design pattern described by Martin Fowler as <quote> [maintaining] a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems. PoEAA In other words, its a series of operations we wish to carry out against the database together. Basically, it is a transaction, though fulfilling a unit of work will often span multiple physical database transactions (see ). So really we are talking about a more abstract notion of a transaction. The term \"business transaction\" is also sometimes used in lieu of unit of work."
msgstr "首先,让我们定义一个工作å•å…ƒï¼ˆunit of work)。工作å•å…ƒæ˜¯ä¸€ä¸ªè®¾è®¡æ¨¡å¼ï¼ŒMartin Fowler 把它æ述为 <quote> [maintaining] a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems. PoEAA æ¢å¥è¯è¯´ï¼Œå®ƒæ˜¯æˆ‘们希望对数æ®åº“执行的一系列æ“作。基本上,它是一个事务,虽然完æˆä¸€ä¸ªå·¥ä½œå•å…ƒç»å¸¸å°†è·¨è¶Šå¤šä¸ªç‰©ç†æ•°æ®åº“事务(请å‚考 ï¼‰ã€‚æ‰€ä»¥ï¼Œå®žé™…ä¸Šæˆ‘ä»¬åœ¨è®¨è®ºä¸€ä¸ªæ›´æŠ½è±¡çš„äº‹åŠ¡æ¦‚å¿µã€‚æœ¯è¯ \"business transaction\" 有时也和工作å•å…ƒä¸€èµ·ä½¿ç”¨ã€‚"
#. Tag: para
#, no-c-format
msgid "Do not use the <emphasis>session-per-operation antipattern: do not open and close a Session for every simple database call in a single thread. The same is true for database transactions. Database calls in an application are made using a planned sequence; they are grouped into atomic units of work. This also means that auto-commit after every single SQL statement is useless in an application as this mode is intended for ad-hoc SQL console work. Hibernate disables, or expects the application server to disable, auto-commit mode immediately. Database transactions are never optional. All communication with a database has to occur inside a transaction. Auto-commit behavior for reading data should be avoided, as many small transactions are unlikely to perform better than one clearly defined unit of work. The latter is also more maintainable and extensible."
msgstr "首先,别用 <emphasis>session-per-operation è¿™ç§å模å¼äº†ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œåœ¨å•ä¸ªçº¿ç¨‹ä¸ï¼Œ ä¸è¦å› 为一次简å•çš„æ•°æ®åº“调用,就打开和关é—一次 Session ï¼æ•°æ®åº“事务也是如æ¤ã€‚ 应用程åºä¸çš„æ•°æ®åº“调用是按照计划好的次åºï¼Œåˆ†ç»„为原åçš„æ“作å•å…ƒã€‚(注æ„,这也æ„味ç€ï¼Œåº”用程 åºä¸ï¼Œåœ¨å•ä¸ªçš„ SQL è¯å¥å‘é€ä¹‹åŽï¼Œè‡ªåŠ¨äº‹åŠ¡æ交(auto-commit)模å¼å¤±æ•ˆäº†ã€‚è¿™ç§æ¨¡å¼ä¸“门为SQL控制å°æ“作设计的。 Hibernate ç¦æ¢ç«‹å³è‡ªåŠ¨äº‹åŠ¡æ交模å¼ï¼Œæˆ–者期望应用æœåŠ¡å™¨ç¦æ¢ç«‹å³è‡ªåŠ¨äº‹åŠ¡æ交模å¼ã€‚)数æ®åº“事务ç»ä¸æ˜¯å¯æœ‰å¯æ— 的,任何与数æ®åº“之间的通讯都必须在æŸä¸ªäº‹åŠ¡ä¸è¿›è¡Œï¼Œä¸ç®¡ä½ 是在读还是在写数æ®ã€‚对读数æ®è€Œè¨€ï¼Œåº”该é¿å… auto-commit è¡Œä¸ºï¼Œå› ä¸ºå¾ˆå¤šå°çš„事务比一个清晰定义的工作å•å…ƒæ€§èƒ½å·®ã€‚åŽè€…也更容易维护和扩展。 "
#. Tag: para
#, no-c-format
msgid "The most common pattern in a multi-user client/server application is <emphasis>session-per-request. In this model, a request from the client is sent to the server, where the Hibernate persistence layer runs. A new Hibernate Session is opened, and all database operations are executed in this unit of work. On completion of the work, and once the response for the client has been prepared, the session is flushed and closed. Use a single database transaction to serve the clients request, starting and committing it when you open and close the Session . The relationship between the two is one-to-one and this model is a perfect fit for many applications."
msgstr "在多用户的 client/server 应用程åºä¸ï¼Œæœ€å¸¸ç”¨çš„模å¼æ˜¯ <emphasis>æ¯ä¸ªè¯·æ±‚一个会è¯ï¼ˆsession-per-request)。 在这ç§æ¨¡å¼ä¸‹ï¼Œæ¥è‡ªå®¢æˆ·ç«¯çš„请求被å‘é€åˆ°æœåŠ¡å™¨ç«¯ï¼ˆå³ Hibernate æŒä¹…化层è¿è¡Œçš„地方),一个新的 Hibernate Session 被打开,并且执行这个æ“作å•å…ƒä¸æ‰€æœ‰çš„æ•°æ®åº“æ“作。一旦æ“作完æˆï¼ˆåŒæ—¶å¯¹å®¢æˆ·ç«¯çš„å“应也准备就绪),session 被åŒæ¥ï¼Œç„¶åŽå…³é—ã€‚ä½ ä¹Ÿå¯ä»¥ä½¿ç”¨å• 个数æ®åº“事务æ¥å¤„ç†å®¢æˆ·ç«¯è¯·æ±‚ï¼Œåœ¨ä½ æ‰“å¼€ Session 之åŽå¯åŠ¨äº‹åŠ¡ï¼Œåœ¨ä½ å…³é— Session 之å‰æ交事务。会è¯å’Œè¯·æ±‚之间的关系是一对一的关系,这ç§æ¨¡å¼å¯¹ 于大多数应用程åºæ¥è¯´æ˜¯å¾ˆæ£’的。 "
#. Tag: para
#, no-c-format
msgid "The challenge lies in the implementation. Hibernate provides built-in management of the \"current session\" to simplify this pattern. Start a transaction when a server request has to be processed, and end the transaction before the response is sent to the client. Common solutions are <literal>ServletFilter, AOP interceptor with a pointcut on the service methods, or a proxy/interception container. An EJB container is a standardized way to implement cross-cutting aspects such as transaction demarcation on EJB session beans, declaratively with CMT. If you use programmatic transaction demarcation, for ease of use and code portability use the Hibernate Transaction API shown later in this chapter."
msgstr "实现æ‰æ˜¯çœŸæ£çš„挑战。Hibernate 内置了对\"å½“å‰ session(current session)\" 的管ç†ï¼Œç”¨äºŽç®€åŒ–æ¤æ¨¡å¼ã€‚ä½ è¦åšçš„一切就是在æœåŠ¡å™¨ç«¯è¦å¤„ç†è¯·æ±‚的时候,开å¯äº‹åŠ¡ï¼Œåœ¨å“应å‘é€ç»™å®¢æˆ·ä¹‹å‰ç»“æŸäº‹åŠ¡ã€‚ä½ å¯ä»¥ç”¨ä»»ä½•æ–¹å¼æ¥å®Œæˆè¿™ä¸€æ“作,通常的方案有 <literal>ServletFilter,在 service 方法ä¸è¿›è¡Œ pointcut çš„ AOP 拦截器,或者 proxy/interception 容器。EJB 容器是实现横切诸如 EJB session bean 上的事务分界,用 CMT 对事务进行声明ç‰æ–¹é¢çš„æ ‡å‡†æ‰‹æ®µã€‚å‡è‹¥ä½ 决定使用编程å¼çš„事务分界,请å‚è€ƒæœ¬ç« åŽé¢è®²åˆ°çš„ Hibernate Transaction API,这对易用性和代ç å¯ç§»æ¤æ€§éƒ½æœ‰å¥½å¤„。 "
#. Tag: para
#, no-c-format
msgid "Your application code can access a \"current session\" to process the request by calling <literal>sessionFactory.getCurrentSession(). You will always get a Session scoped to the current database transaction. This has to be configured for either resource-local or JTA environments, see ."
msgstr "åœ¨ä»»ä½•æ—¶é—´ï¼Œä»»ä½•åœ°æ–¹ï¼Œä½ çš„åº”ç”¨ä»£ç å¯ä»¥é€šè¿‡ç®€å•çš„调用<literal>sessionFactory.getCurrentSession() æ¥è®¿é—®\"å½“å‰ session\",用于处ç†è¯·æ±‚ã€‚ä½ æ€»æ˜¯ä¼šå¾—åˆ°å½“å‰æ•°æ®åº“事务范围内的 Session 。在使用本地资æºæˆ– JTA 环境时,必须é…置它,请å‚è§ ã€‚"
#. Tag: para
#, no-c-format
msgid "You can extend the scope of a <literal>Session and database transaction until the \"view has been rendered\". This is especially useful in servlet applications that utilize a separate rendering phase after the request has been processed. Extending the database transaction until view rendering, is achieved by implementing your own interceptor. However, this will be difficult if you rely on EJBs with container-managed transactions. A transaction will be completed when an EJB method returns, before rendering of any view can start. See the Hibernate website and forum for tips and examples relating to this Open Session in View pattern."
msgstr "有时,将 <literal>Session 和数æ®åº“事务的边界延伸到\"展示层被渲染åŽ\"会带æ¥ä¾¿åˆ©ã€‚有些 serlvet 应用程åºåœ¨å¯¹è¯·æ±‚进行处ç†åŽï¼Œæœ‰ä¸ªå•ç‹¬çš„渲染期,这ç§å»¶ä¼¸å¯¹è¿™ç§ç¨‹åºç‰¹åˆ«æœ‰ç”¨ã€‚å‡è‹¥ä½ å®žçŽ°ä½ è‡ªå·±çš„æ‹¦æˆªå™¨ï¼ŒæŠŠäº‹åŠ¡è¾¹ç•Œå»¶ä¼¸åˆ°å±•ç¤ºå±‚æ¸²æŸ“ç»“æŸåŽéžå¸¸å®¹æ˜“。然而,å‡è‹¥ä½ ä¾èµ–有容器管ç†äº‹åŠ¡çš„ EJB,这就ä¸å¤ªå®¹æ˜“äº†ï¼Œå› ä¸ºäº‹åŠ¡ä¼šåœ¨ EJB 方法返回åŽç»“æŸï¼Œè€Œé‚£æ˜¯åœ¨ä»»ä½•å±•ç¤ºå±‚渲染开始之å‰ã€‚请访问 Hibernate 网站和论å›ï¼Œä½ å¯ä»¥æ‰¾åˆ° Open Session in View 这一模å¼çš„æ示和示例。 "
#. Tag: title
#, no-c-format
msgid "Long conversations"
msgstr "长对è¯"
#. Tag: para
#, no-c-format
msgid "The session-per-request pattern is not the only way of designing units of work. Many business processes require a whole series of interactions with the user that are interleaved with database accesses. In web and enterprise applications, it is not acceptable for a database transaction to span a user interaction. Consider the following example:"
msgstr "session-per-request 模å¼ä¸ä»…仅是一个å¯ä»¥ç”¨æ¥è®¾è®¡æ“作å•å…ƒçš„有用概念。很多业务处ç†éƒ½éœ€ è¦ä¸€ç³»åˆ—完整的与用户之间的交互,而这些用户是指对数æ®åº“有交å‰è®¿é—®çš„用户。在基于 web 的应用和ä¼ä¸šåº”用ä¸ï¼Œè·¨ç”¨æˆ·äº¤äº’çš„æ•°æ®åº“äº‹åŠ¡æ˜¯æ— æ³•æŽ¥å—的。考虑下é¢çš„例å: "
#. Tag: para
#, no-c-format
msgid "The first screen of a dialog opens. The data seen by the user has been loaded in a particular <literal>Session and database transaction. The user is free to modify the objects."
msgstr "在界é¢çš„第一å±ï¼Œæ‰“开对è¯æ¡†ï¼Œç”¨æˆ·æ‰€çœ‹åˆ°çš„æ•°æ®æ˜¯è¢«ä¸€ä¸ªç‰¹å®šçš„ <literal>Session å’Œæ•°æ® åº“äº‹åŠ¡è½½å…¥ï¼ˆload)的。用户å¯ä»¥éšæ„修改对è¯æ¡†ä¸çš„æ•°æ®å¯¹è±¡ã€‚ "
#. Tag: para
#, no-c-format
msgid "The user clicks \"Save\" after 5 minutes and expects their modifications to be made persistent. The user also expects that they were the only person editing this information and that no conflicting modification has occurred."
msgstr "5 分钟åŽï¼Œç”¨æˆ·ç‚¹å‡»â€œä¿å˜â€ï¼ŒæœŸæœ›æ‰€åšå‡ºçš„修改被æŒä¹…化;åŒæ—¶ä»–也期望自己是唯一修改这个信æ¯çš„人,ä¸ä¼šå‡ºçŽ°ä¿®æ”¹å†²çªã€‚ "
#. Tag: para
#, no-c-format
msgid "From the point of view of the user, we call this unit of work a long-running <emphasis>conversation or application transaction . There are many ways to implement this in your application."
msgstr "从用户的角度æ¥çœ‹ï¼Œæˆ‘们把这个æ“作å•å…ƒç§°ä¸ºé•¿æ—¶é—´è¿è¡Œçš„<emphasis>对è¯ï¼ˆconversation),或者应用事务 (application transactionï¼‰ã€‚åœ¨ä½ çš„åº”ç”¨ç¨‹åºä¸ï¼Œå¯ä»¥æœ‰å¾ˆå¤šç§æ–¹æ³•æ¥å®žçŽ°å®ƒã€‚"
#. Tag: para
#, no-c-format
msgid "A first naive implementation might keep the <literal>Session and database transaction open during user think time, with locks held in the database to prevent concurrent modification and to guarantee isolation and atomicity. This is an anti-pattern, since lock contention would not allow the application to scale with the number of concurrent users."
msgstr "头一个幼稚的åšæ³•æ˜¯ï¼Œåœ¨ç”¨æˆ·æ€è€ƒçš„过程ä¸ï¼Œä¿æŒ <literal>Session 和数æ®åº“事务是打开的,ä¿æŒæ•°æ®åº“é”定,以阻æ¢å¹¶å‘修改,从而ä¿è¯æ•°æ®åº“事务隔离级别和原åæ“作。这ç§æ–¹å¼å½“然是一个å模å¼ï¼Œå› 为é”争用会导致应用程åºæ— 法扩展并å‘用户的数目。 "
#. Tag: para
#, no-c-format
msgid "You have to use several database transactions to implement the conversation. In this case, maintaining isolation of business processes becomes the partial responsibility of the application tier. A single conversation usually spans several database transactions. It will be atomic if only one of these database transactions (the last one) stores the updated data. All others simply read data (for example, in a wizard-style dialog spanning several request/response cycles). This is easier to implement than it might sound, especially if you utilize some of Hibernate's features:"
msgstr "很明显,我们必须使用多个数æ®åº“事务æ¥å®žçŽ°è¿™ä¸ªå¯¹è¯ã€‚在这个例åä¸ï¼Œç»´æŠ¤ä¸šåŠ¡å¤„ç†çš„ 事务隔离å˜æˆäº†åº”用程åºå±‚的部分责任。一个对è¯é€šå¸¸è·¨è¶Šå¤šä¸ªæ•°æ®åº“事务。如果仅仅åªæœ‰ä¸€ä¸ªæ•°æ®åº“事务(最åŽçš„那个事务)ä¿å˜æ›´æ–°è¿‡çš„æ•°æ®ï¼Œè€Œæ‰€æœ‰å…¶ä»–事务åªæ˜¯å•çº¯çš„读å–æ•°æ®ï¼ˆä¾‹å¦‚在一个跨越多个请求/å“应周期的å‘å¯¼é£Žæ ¼çš„å¯¹è¯æ¡†ä¸ï¼‰ï¼Œé‚£ä¹ˆåº”用程åºäº‹åŠ¡å°†ä¿è¯å…¶åŽŸå性。这ç§æ–¹å¼æ¯”å¬èµ·æ¥è¿˜è¦å®¹æ˜“å®žçŽ°ï¼Œç‰¹åˆ«æ˜¯å½“ä½ ä½¿ç”¨äº† Hibernate 的下述特性的时候: "
#. Tag: para
#, no-c-format
msgid "<emphasis>Automatic Versioning: Hibernate can perform automatic optimistic concurrency control for you. It can automatically detect if a concurrent modification occurred during user think time. Check for this at the end of the conversation."
msgstr "<emphasis>自动版本化:Hibernate 能够自动进行ä¹è§‚并å‘控制,如果在用户æ€è€ƒçš„过程ä¸å‘生并å‘修改,Hibernate 能够自动检测到。一般我们åªåœ¨å¯¹è¯ç»“æŸæ—¶æ‰æ£€æŸ¥ã€‚"
#. Tag: para
#, no-c-format
msgid "<emphasis>Detached Objects: if you decide to use the session-per-request pattern, all loaded instances will be in the detached state during user think time. Hibernate allows you to reattach the objects and persist the modifications. The pattern is called session-per-request-with-detached-objects . Automatic versioning is used to isolate concurrent modifications."
msgstr "<emphasis>脱管对象(Detached Objectsï¼‰ï¼šå¦‚æžœä½ å†³å®šé‡‡ç”¨å‰é¢å·²ç»è®¨è®ºè¿‡çš„ session-per-request 模å¼ï¼Œæ‰€æœ‰è½½å…¥çš„实例在用户æ€è€ƒçš„过程ä¸éƒ½å¤„于与 Session 脱离的状æ€ã€‚Hibernate å…è®¸ä½ æŠŠä¸Ž Session 脱离的对象é‡æ–°å…³è”到 Session 上,并且对修改进行æŒä¹…化,这ç§æ¨¡å¼è¢«ç§°ä¸º session-per-request-with-detached-objects 。自动版本化被用æ¥éš”离并å‘修改。"
#. Tag: para
#, no-c-format
msgid "<emphasis>Extended (or Long) Session: the Hibernate Session can be disconnected from the underlying JDBC connection after the database transaction has been committed and reconnected when a new client request occurs. This pattern is known as session-per-conversation and makes even reattachment unnecessary. Automatic versioning is used to isolate concurrent modifications and the Session will not be allowed to be flushed automatically, but explicitly."
msgstr "<emphasis>Extended (or Long) Session:Hibernate çš„ Session å¯ä»¥åœ¨æ•°æ®åº“事务æ交之åŽå’Œåº•å±‚çš„ JDBC 连接æ–开,当一个新的客户端请求到æ¥çš„时候,它åˆé‡æ–°è¿žæŽ¥ä¸Šåº•å±‚çš„ JDBC 连接。这ç§æ¨¡å¼è¢«ç§°ä¹‹ä¸ºsession-per-conversation ,这ç§æƒ…å†µå¯ èƒ½ä¼šé€ æˆä¸å¿…è¦çš„ Session å’Œ JDBC 连接的é‡æ–°å…³è”。自动版本化被用æ¥éš”离并å‘修改,Session 通常ä¸å…许自动 flush,而是显性地 flush。 "
#. Tag: para
#, no-c-format
msgid "Both <emphasis>session-per-request-with-detached-objects and session-per-conversation have advantages and disadvantages. These disadvantages are discussed later in this chapter in the context of optimistic concurrency control."
msgstr "<emphasis>session-per-request-with-detached-objects å’Œ session-per-conversation å„æœ‰ä¼˜ç¼ºç‚¹ï¼Œæˆ‘ä»¬åœ¨æœ¬ç« åŽé¢ä¹è§‚并å‘控制那部分å†è¿›è¡Œè®¨è®ºã€‚ "
#. Tag: title
#, no-c-format
msgid "Considering object identity"
msgstr "å…³æ³¨å¯¹è±¡æ ‡è¯†ï¼ˆConsidering object identity)"
#. Tag: para
#, no-c-format
msgid "An application can concurrently access the same persistent state in two different <literal>Sessions. However, an instance of a persistent class is never shared between two Session instances. It is for this reason that there are two different notions of identity:"
msgstr "应用程åºå¯èƒ½åœ¨ä¸¤ä¸ªä¸åŒçš„ <literal>Session ä¸å¹¶å‘访问åŒä¸€æŒä¹…化状æ€ï¼Œä½†æ˜¯ï¼Œä¸€ä¸ªæŒä¹…åŒ–ç±»çš„å®žä¾‹æ— æ³•åœ¨ä¸¤ä¸ª Session ä¸å…±äº«ã€‚å› æ¤æœ‰ä¸¤ç§ä¸åŒçš„æ ‡è¯†è¯ä¹‰ï¼š "
#. Tag: term
#, no-c-format
msgid "Database Identity"
msgstr "æ•°æ®åº“æ ‡è¯†"
#. Tag: para
#, no-c-format
msgid "<literal>foo.getId().equals( bar.getId() )"
msgstr "<literal>foo.getId().equals( bar.getId() ) "
#. Tag: term
#, no-c-format
msgid "JVM Identity"
msgstr "JVM æ ‡è¯†"
#. Tag: para
#, no-c-format
msgid "<literal>foo==bar"
msgstr "<literal>foo==bar"
#. Tag: para
#, no-c-format
msgid "For objects attached to a <emphasis>particular Session (i.e., in the scope of a Session ), the two notions are equivalent and JVM identity for database identity is guaranteed by Hibernate. While the application might concurrently access the \"same\" (persistent identity) business object in two different sessions, the two instances will actually be \"different\" (JVM identity). Conflicts are resolved using an optimistic approach and automatic versioning at flush/commit time."
msgstr "对于那些关è”到 <emphasis>特定 Session (也就是在å•ä¸ª Session 的范围内)上的对象æ¥è¯´ï¼Œè¿™ä¸¤ç§æ ‡è¯†çš„è¯ä¹‰æ˜¯ç‰ä»·çš„,与数æ®åº“æ ‡è¯†å¯¹åº”çš„ JVM æ ‡è¯†æ˜¯ç”± Hibernate æ¥ä¿è¯çš„。ä¸è¿‡ï¼Œå½“应用程åºåœ¨ä¸¤ä¸ªä¸åŒçš„ session ä¸å¹¶å‘访问具有åŒä¸€æŒä¹…åŒ–æ ‡è¯†çš„ä¸šåŠ¡å¯¹è±¡å®žä¾‹çš„æ—¶å€™ï¼Œè¿™ä¸ªä¸šåŠ¡å¯¹è±¡çš„ä¸¤ä¸ªå®žä¾‹äº‹å®žä¸Šæ˜¯ä¸ç›¸åŒçš„(从 JVM 识别æ¥çœ‹ï¼‰ã€‚è¿™ç§å†²çªå¯ä»¥é€šè¿‡åœ¨åŒæ¥å’Œæ交的时候使用自动版本化和ä¹è§‚é”定方法æ¥è§£å†³ã€‚ "
#. Tag: para
#, no-c-format
msgid "This approach leaves Hibernate and the database to worry about concurrency. It also provides the best scalability, since guaranteeing identity in single-threaded units of work means that it does not need expensive locking or other means of synchronization. The application does not need to synchronize on any business object, as long as it maintains a single thread per <literal>Session. Within a Session the application can safely use == to compare objects."
msgstr "è¿™ç§æ–¹å¼æŠŠå…³äºŽå¹¶å‘的头疼问题留给了 Hibernate 和数æ®åº“;由于在å•ä¸ªçº¿ç¨‹å†…,æ“作å•å…ƒä¸çš„å¯¹è±¡è¯†åˆ«ä¸ éœ€è¦ä»£ä»·æ˜‚贵的é”定或其他æ„义上的åŒæ¥ï¼Œå› æ¤å®ƒåŒæ—¶å¯ä»¥æ供最好的å¯ä¼¸ç¼©æ€§ã€‚åªè¦åœ¨å•ä¸ªçº¿ç¨‹åªæŒæœ‰ä¸€ä¸ª <literal>Session,应用程åºå°±ä¸éœ€è¦åŒæ¥ä»»ä½•ä¸šåŠ¡å¯¹è±¡ã€‚在 Session 的范围内,应用程åºå¯ä»¥æ”¾å¿ƒçš„使用 == 进行对象比较。 "
#. Tag: para
#, no-c-format
msgid "However, an application that uses <literal>== outside of a Session might produce unexpected results. This might occur even in some unexpected places. For example, if you put two detached instances into the same Set , both might have the same database identity (i.e., they represent the same row). JVM identity, however, is by definition not guaranteed for instances in a detached state. The developer has to override the equals() and hashCode() methods in persistent classes and implement their own notion of object equality. There is one caveat: never use the database identifier to implement equality. Use a business key that is a combination of unique, usually immutable, attributes. The database identifier will change if a transient object is made persistent. If the transient instance (usually together with detached instances) is held in a Set , changing the hashcode breaks the contract of the Set . Attributes for business keys do not have to be as stable as database primary keys; you only have to guarantee stability as long as the objects are in the same Set . See the Hibernate website for a more thorough discussion of this issue. Please note that this is not a Hibernate issue, but simply how Java object identity and equality has to be implemented."
msgstr "ä¸è¿‡ï¼Œåº”用程åºåœ¨ <literal>Session 的外é¢ä½¿ç”¨ == 进行对象比较å¯èƒ½ä¼š å¯¼è‡´æ— æ³•é¢„æœŸçš„ç»“æžœã€‚åœ¨ä¸€äº›æ— æ³•é¢„æ–™çš„åœºåˆï¼Œä¾‹å¦‚ï¼Œå¦‚æžœä½ æŠŠä¸¤ä¸ªè„±ç®¡å¯¹è±¡å®žä¾‹æ”¾è¿›åŒä¸€ä¸ª Set 的时候,就å¯èƒ½å‘生。这两个对象实例å¯èƒ½æœ‰åŒä¸€ä¸ªæ•°æ®åº“æ ‡è¯†ï¼ˆä¹Ÿå°±æ˜¯è¯´ï¼Œ 他们代表了表的åŒä¸€è¡Œæ•°æ®ï¼‰ï¼Œä»Ž JVM æ ‡è¯†çš„å®šä¹‰ä¸Šæ¥è¯´ï¼Œå¯¹è„±ç®¡çš„对象而言,Hibernate æ— æ³•ä¿è¯ä»–们 çš„çš„ JVM æ ‡è¯†ä¸€è‡´ã€‚å¼€å‘人员必须覆盖æŒä¹…化类的 equals() 方法和 hashCode() 方法,从而实现自定义的对象相ç‰è¯ä¹‰ã€‚è¦å‘Šï¼šä¸è¦ä½¿ç”¨æ•°æ®åº“æ ‡è¯†æ¥å®žçŽ°å¯¹è±¡ç›¸ç‰ï¼Œåº”该使用业务键值,由唯一的,通常ä¸å˜çš„属性组æˆã€‚当一个瞬时对象被æŒä¹…化的时候,它的数æ®åº“æ ‡è¯†ä¼šå‘生改å˜ã€‚如果一个瞬时对象(通常也包括脱管对象实例)被放入一个 Set ,改å˜å®ƒçš„ hashcode 会导致与这个 Set 的关系ä¸æ–。虽 然业务键值的属性ä¸è±¡æ•°æ®åº“ä¸»é”®é‚£æ ·ç¨³å®šä¸å˜ï¼Œä½†æ˜¯ä½ åªéœ€è¦ä¿è¯åœ¨åŒä¸€ä¸ª Set ä¸çš„对象属性的稳定性就足够了。请到 Hibernate 网站去寻求这个问题更多的详细的讨论。请注æ„,这ä¸æ˜¯ä¸€ä¸ªæœ‰å…³ Hibernate 的问题,而仅仅是一个关于 Java å¯¹è±¡æ ‡è¯†å’Œåˆ¤ç‰è¡Œä¸ºå¦‚何实现的问题。 "
#. Tag: title
#, no-c-format
msgid "Common issues"
msgstr "常è§é—®é¢˜"
#. Tag: para
#, no-c-format
msgid "Do not use the anti-patterns <emphasis>session-per-user-session or session-per-application (there are, however, rare exceptions to this rule). Some of the following issues might also arise within the recommended patterns, so ensure that you understand the implications before making a design decision:"
msgstr "决ä¸è¦ä½¿ç”¨åæ¨¡å¼ <emphasis>session-per-user-session 或者 session-per-application ï¼ˆå½“ç„¶ï¼Œè¿™ä¸ªè§„å®šå‡ ä¹Žæ²¡æœ‰ä¾‹å¤–ï¼‰ã€‚è¯·æ³¨æ„,下述一些问题å¯èƒ½ä¹Ÿä¼šå‡ºçŽ°åœ¨æˆ‘们推è的模å¼ä¸ï¼Œåœ¨ä½ 作出æŸä¸ªè®¾è®¡å†³å®šä¹‹å‰ï¼Œè¯·åŠ¡å¿…ç†è§£è¯¥æ¨¡å¼çš„应用å‰æ。 "
#. Tag: para
#, no-c-format
msgid "A <literal>Session is not thread-safe. Things that work concurrently, like HTTP requests, session beans, or Swing workers, will cause race conditions if a Session instance is shared. If you keep your Hibernate Session in your HttpSession (this is discussed later in the chapter), you should consider synchronizing access to your Http session. Otherwise, a user that clicks reload fast enough can use the same Session in two concurrently running threads."
msgstr "<literal>Session 对象是éžçº¿ç¨‹å®‰å…¨çš„。如果一个 Session 实例å…许共享的è¯ï¼Œé‚£äº›æ”¯æŒå¹¶å‘è¿è¡Œçš„东东,例如 HTTP request,session beans 或者是 Swing workers,将会导致出现资æºäº‰ç”¨ï¼ˆrace condition)。如果在 HttpSession ä¸æœ‰ Hibernate çš„ Session çš„è¯ï¼ˆç¨åŽè®¨è®ºï¼‰ï¼Œä½ 应该考虑åŒæ¥è®¿é—®ä½ çš„ Http session。 å¦åˆ™ï¼Œåªè¦ç”¨æˆ·è¶³å¤Ÿå¿«çš„点击æµè§ˆå™¨çš„“刷新â€ï¼Œå°±ä¼šå¯¼è‡´ä¸¤ä¸ªå¹¶å‘è¿è¡Œçº¿ç¨‹ä½¿ç”¨åŒä¸€ä¸ª Session 。 "
#. Tag: para
#, no-c-format
msgid "An exception thrown by Hibernate means you have to rollback your database transaction and close the <literal>Session immediately (this is discussed in more detail later in the chapter). If your Session is bound to the application, you have to stop the application. Rolling back the database transaction does not put your business objects back into the state they were at the start of the transaction. This means that the database state and the business objects will be out of sync. Usually this is not a problem, because exceptions are not recoverable and you will have to start over after rollback anyway."
msgstr "一个由 Hibernate 抛出的异常æ„味ç€ä½ 必须立å³å›žæ»šæ•°æ®åº“事务,并立å³å…³é— <literal>Session(ç¨åŽä¼šå±•å¼€è®¨è®ºï¼‰ã€‚å¦‚æžœä½ çš„ Session 绑定到一个应用程åºä¸Šï¼Œä½ å¿…é¡»åœæ¢è¯¥åº”用程åºã€‚回滚数æ®åº“事务并ä¸ä¼šæŠŠä½ 的业务对象退回到事务å¯åŠ¨æ—¶å€™çš„状æ€ã€‚è¿™æ„味ç€æ•°æ®åº“状æ€å’Œä¸šåŠ¡å¯¹è±¡çŠ¶æ€ä¸åŒæ¥ã€‚通常情况下,这ä¸æ˜¯ä»€ä¹ˆé—®é¢˜ï¼Œå› 为异常是ä¸å¯æ¢å¤çš„ï¼Œä½ å¿…é¡»åœ¨å›žæ»šä¹‹åŽé‡æ–°å¼€å§‹æ‰§è¡Œã€‚ "
#. Tag: para
#, no-c-format
msgid "The <literal>Session caches every object that is in a persistent state (watched and checked for dirty state by Hibernate). If you keep it open for a long time or simply load too much data, it will grow endlessly until you get an OutOfMemoryException. One solution is to call clear() and evict() to manage the Session cache, but you should consider a Stored Procedure if you need mass data operations. Some solutions are shown in . Keeping a Session open for the duration of a user session also means a higher probability of stale data."
msgstr "<literal>Session 缓å˜äº†å¤„于æŒä¹…化状æ€çš„æ¯ä¸ªå¯¹è±¡ï¼ˆHibernate 会监视和检查è„æ•°æ®ï¼‰ã€‚ è¿™æ„味ç€ï¼Œå¦‚æžœä½ è®© Session 打开很长一段时间,或是仅仅载入了过多的数æ®ï¼Œ Session å 用的内å˜ä¼šä¸€ç›´å¢žé•¿ï¼Œç›´åˆ°æŠ›å‡º OutOfMemoryException 异常。这个 问题的一个解决方法是调用 clear() å’Œ evict() æ¥ç®¡ç† Session 的缓å˜ï¼Œä½†æ˜¯å¦‚æžœä½ éœ€è¦å¤§æ‰¹é‡æ•°æ®æ“作的è¯ï¼Œæœ€å¥½è€ƒè™‘使用å˜å‚¨è¿‡ç¨‹ã€‚在ä¸æœ‰ä¸€äº›è§£å†³æ–¹æ¡ˆã€‚在用户会è¯æœŸé—´ä¸€ç›´ä¿æŒ Session 打开也æ„味ç€å‡ºçŽ°è„æ•°æ®çš„å¯èƒ½æ€§å¾ˆé«˜ã€‚ "
#. Tag: title
#, no-c-format
msgid "Database transaction demarcation"
msgstr "æ•°æ®åº“事务声明"
#. Tag: para
#, no-c-format
msgid "Database, or system, transaction boundaries are always necessary. No communication with the database can occur outside of a database transaction (this seems to confuse many developers who are used to the auto-commit mode). Always use clear transaction boundaries, even for read-only operations. Depending on your isolation level and database capabilities this might not be required, but there is no downside if you always demarcate transactions explicitly. Certainly, a single database transaction is going to perform better than many small transactions, even for reading data."
msgstr "æ•°æ®åº“(或者系统)事务的声明总是必须的。在数æ®åº“äº‹åŠ¡ä¹‹å¤–ï¼Œå°±æ— æ³•å’Œæ•°æ®åº“通讯(这å¯èƒ½ä¼šè®©é‚£äº›ä¹ 惯于自动æ交事务模å¼çš„å¼€å‘人员感到迷惑)。永远使用清晰的事务声明,å³ä½¿åªè¯»æ“作也是如æ¤ã€‚进行 显å¼çš„事务声明并ä¸æ€»æ˜¯éœ€è¦çš„,这å–å†³äºŽä½ çš„äº‹åŠ¡éš”ç¦»çº§åˆ«å’Œæ•°æ®åº“的能力,但ä¸ç®¡æ€Žä¹ˆè¯´ï¼Œå£°æ˜Žäº‹åŠ¡æ€»å½’æœ‰ç›Šæ— å®³ã€‚å½“ç„¶ï¼Œä¸€ä¸ªå•ç‹¬çš„æ•°æ®åº“事务总是比很多ç碎的事务性能更好,å³æ—¶å¯¹è¯»æ•°æ®è€Œè¨€ä¹Ÿæ˜¯ä¸€æ ·ã€‚ "
#. Tag: para
#, no-c-format
msgid "A Hibernate application can run in non-managed (i.e., standalone, simple Web- or Swing applications) and managed J2EE environments. In a non-managed environment, Hibernate is usually responsible for its own database connection pool. The application developer has to manually set transaction boundaries (begin, commit, or rollback database transactions) themselves. A managed environment usually provides container-managed transactions (CMT), with the transaction assembly defined declaratively (in deployment descriptors of EJB session beans, for example). Programmatic transaction demarcation is then no longer necessary."
msgstr "一个 Hibernate 应用程åºå¯ä»¥è¿è¡Œåœ¨éžæ‰˜ç®¡çŽ¯å¢ƒä¸ï¼ˆä¹Ÿå°±æ˜¯ç‹¬ç«‹è¿è¡Œçš„应用程åºï¼Œç®€å• Web 应用程åºï¼Œæˆ–者Swing图形桌é¢åº”用程åºï¼‰ï¼Œä¹Ÿå¯ä»¥è¿è¡Œåœ¨æ‰˜ç®¡çš„ J2EE 环境ä¸ã€‚在一个éžæ‰˜ç®¡çŽ¯å¢ƒä¸ï¼ŒHibernate 通常自己负责管ç†æ•°æ®åº“è¿žæŽ¥æ± ã€‚åº”ç”¨ç¨‹åºå¼€å‘人员必须手工设置事务声明,æ¢å¥è¯è¯´ï¼Œå°±æ˜¯æ‰‹å·¥å¯ 动,æ交,或者回滚数æ®åº“事务。一个托管的环境通常æ供了容器管ç†äº‹åŠ¡ï¼ˆCMT),例如事务装é…通过å¯å£°æ˜Žçš„æ–¹å¼å®šä¹‰åœ¨ EJB session beans 的部署æ述符ä¸ã€‚å¯ç¼–程å¼äº‹åŠ¡å£°æ˜Žä¸å†éœ€è¦ï¼Œå³ä½¿æ˜¯ <literal>Session çš„åŒæ¥ä¹Ÿå¯ä»¥è‡ªåŠ¨å®Œæˆã€‚ "
#. Tag: para
#, no-c-format
msgid "However, it is often desirable to keep your persistence layer portable between non-managed resource-local environments, and systems that can rely on JTA but use BMT instead of CMT. In both cases use programmatic transaction demarcation. Hibernate offers a wrapper API called <literal>Transaction that translates into the native transaction system of your deployment environment. This API is actually optional, but we strongly encourage its use unless you are in a CMT session bean."
msgstr "让æŒä¹…层具备å¯ç§»æ¤æ€§æ˜¯äººä»¬çš„ç†æƒ³,è¿™ç§ç§»æ¤å‘生在éžæ‰˜ç®¡çš„本地资æºçŽ¯å¢ƒï¼Œä¸Žä¾èµ– JTA 但是使用 BMT è€Œéž CMT 的系统之间。在两ç§æƒ…å†µä¸‹ä½ éƒ½å¯ä»¥ä½¿ç”¨ç¼–程å¼çš„事务管ç†ã€‚Hibernate æ供了一套称为 <literal>Transaction çš„å°è£… API, 用æ¥æŠŠä½ 的部署环境ä¸çš„本地事务管ç†ç³»ç»Ÿè½¬æ¢åˆ° Hibernate 事务上。这个 API 是å¯é€‰çš„,但是我们强烈推èä½ ä½¿ç”¨ï¼Œé™¤éžä½ 用 CMT session bean。 "
#. Tag: para
#, no-c-format
msgid "Ending a <literal>Session usually involves four distinct phases:"
msgstr "é€šå¸¸æƒ…å†µä¸‹ï¼Œç»“æŸ <literal>Session 包å«äº†å››ä¸ªä¸åŒçš„阶段: "
#. Tag: para
#, no-c-format
msgid "flush the session"
msgstr "åŒæ¥ session(flush,刷出到ç£ç›˜ï¼‰"
#. Tag: para
#, no-c-format
msgid "commit the transaction"
msgstr "æ交事务"
#. Tag: para
#, no-c-format
msgid "close the session"
msgstr "å…³é— session"
#. Tag: para
#, no-c-format
msgid "handle exceptions"
msgstr "处ç†å¼‚常"
#. Tag: para
#, no-c-format
msgid "We discussed Flushing the session earlier, so we will now have a closer look at transaction demarcation and exception handling in both managed and non-managed environments."
msgstr "session çš„åŒæ¥ï¼ˆflush,刷出)å‰é¢å·²ç»è®¨è®ºè¿‡äº†ï¼Œæˆ‘们现在进一æ¥è€ƒå¯Ÿåœ¨æ‰˜ç®¡å’Œéžæ‰˜ç®¡çŽ¯å¢ƒä¸‹çš„事务声明和异常处ç†ã€‚ "
#. Tag: title
#, no-c-format
msgid "Non-managed environment"
msgstr "éžæ‰˜ç®¡çŽ¯å¢ƒ"
#. Tag: para
#, no-c-format
msgid "If a Hibernate persistence layer runs in a non-managed environment, database connections are usually handled by simple (i.e., non-DataSource) connection pools from which Hibernate obtains connections as needed. The session/transaction handling idiom looks like this:"
msgstr "如果 Hibernat æŒä¹…层è¿è¡Œåœ¨ä¸€ä¸ªéžæ‰˜ç®¡çŽ¯å¢ƒä¸ï¼Œæ•°æ®åº“连接通常由 Hibernate 的简å•ï¼ˆå³éž DataSourceï¼‰è¿žæŽ¥æ± æœºåˆ¶ æ¥å¤„ç†ã€‚session/transaction 处ç†æ–¹å¼å¦‚下所示: "
#. Tag: para
#, no-c-format
msgid "You do not have to <literal>flush() the Session explicitly: the call to commit() automatically triggers the synchronization depending on the FlushMode for the session. A call to close() marks the end of a session. The main implication of close() is that the JDBC connection will be relinquished by the session. This Java code is portable and runs in both non-managed and JTA environments."
msgstr "ä½ ä¸éœ€è¦æ˜¾å¼ <literal>flush() Session — 对 commit() çš„è°ƒç”¨ä¼šè‡ªåŠ¨è§¦å‘ session çš„åŒæ¥ï¼ˆå–决于 session çš„ )。调用 close() æ ‡å¿— session 的结æŸã€‚close() 方法é‡è¦çš„暗示是,session 释放了 JDBC 连接。这段 Java 代ç 在éžæ‰˜ç®¡çŽ¯å¢ƒä¸‹å’Œ JTA 环境下都å¯ä»¥è¿è¡Œã€‚ "
#. Tag: para
#, no-c-format
msgid "As outlined earlier, a much more flexible solution is Hibernate's built-in \"current session\" context management:"
msgstr "æ›´åŠ çµæ´»çš„方案是 Hibernate 内置的 \"current session\" 上下文管ç†ï¼Œå‰æ–‡å·²ç»è®²è¿‡ï¼š "
#. Tag: para
#, no-c-format
msgid "You will not see these code snippets in a regular application; fatal (system) exceptions should always be caught at the \"top\". In other words, the code that executes Hibernate calls in the persistence layer, and the code that handles <literal>RuntimeException (and usually can only clean up and exit), are in different layers. The current context management by Hibernate can significantly simplify this design by accessing a SessionFactory . Exception handling is discussed later in this chapter."
msgstr "ä½ å¾ˆå¯èƒ½ä»Žæœªåœ¨ä¸€ä¸ªé€šå¸¸çš„应用程åºçš„业务代ç ä¸è§è¿‡è¿™æ ·çš„代ç 片æ–:致命的(系统)异常应该总是 在应用程åºâ€œé¡¶å±‚â€è¢«æ•èŽ·ã€‚æ¢å¥è¯è¯´ï¼Œæ‰§è¡Œ Hibernate 调用的代ç (在æŒä¹…å±‚ï¼‰å’Œå¤„ç† <literal>RuntimeException 异常的代ç (通常åªèƒ½æ¸…ç†å’Œé€€å‡ºåº”用程åºï¼‰åº”该在ä¸åŒ 的应用程åºé€»è¾‘层。Hibernate 的当å‰ä¸Šä¸‹æ–‡ç®¡ç†å¯ä»¥æžå¤§åœ°ç®€åŒ–è¿™ä¸€è®¾è®¡ï¼Œä½ æ‰€æœ‰çš„ä¸€åˆ‡å°±æ˜¯ SessionFactory 。异常处ç†å°†åœ¨æœ¬ç« ç¨åŽè¿›è¡Œè®¨è®ºã€‚ "
#. Tag: para
#, no-c-format
msgid "You should select <literal>org.hibernate.transaction.JDBCTransactionFactory, which is the default, and for the second example select \"thread\" as your hibernate.current_session_context_class ."
msgstr "请注æ„ï¼Œä½ åº”è¯¥é€‰æ‹© <literal>org.hibernate.transaction.JDBCTransactionFactory (这是默认选项),对第二个例åæ¥è¯´ï¼Œhibernate.current_session_context_class 应该是 \"thread\" 。"
#. Tag: title
#, no-c-format
msgid "Using JTA"
msgstr "使用 JTA"
#. Tag: para
#, no-c-format
msgid "If your persistence layer runs in an application server (for example, behind EJB session beans), every datasource connection obtained by Hibernate will automatically be part of the global JTA transaction. You can also install a standalone JTA implementation and use it without EJB. Hibernate offers two strategies for JTA integration."
msgstr "å¦‚æžœä½ çš„æŒä¹…层è¿è¡Œåœ¨ä¸€ä¸ªåº”用æœåŠ¡å™¨ä¸ï¼ˆä¾‹å¦‚,在 EJB session beans çš„åŽé¢ï¼‰ï¼ŒHibernate 获å–çš„æ¯ä¸ªæ•°æ®æºè¿žæŽ¥å°†è‡ªåŠ¨æˆä¸ºå…¨å±€ JTA äº‹åŠ¡çš„ä¸€éƒ¨åˆ†ã€‚ä½ å¯ä»¥å®‰è£…一个独立的 JTA 实现,使用它而ä¸ä½¿ç”¨ EJB。Hibernate æ供了两ç§ç–略进行 JTA 集æˆã€‚ "
#. Tag: para
#, no-c-format
msgid "If you use bean-managed transactions (BMT), Hibernate will tell the application server to start and end a BMT transaction if you use the <literal>Transaction API. The transaction management code is identical to the non-managed environment."
msgstr "å¦‚æžœä½ ä½¿ç”¨ bean 管ç†äº‹åŠ¡ï¼ˆBMT),å¯ä»¥é€šè¿‡ä½¿ç”¨ Hibernate çš„ <literal>Transaction API æ¥å‘Šè¯‰åº”用æœåŠ¡å™¨å¯åŠ¨å’Œç»“æŸ BMT äº‹åŠ¡ã€‚å› æ¤ï¼Œäº‹åŠ¡ç®¡ç†ä»£ç 和在éžæ‰˜ç®¡çŽ¯å¢ƒä¸‹æ˜¯ä¸€æ ·çš„。 "
#. Tag: para
#, no-c-format
msgid "If you want to use a transaction-bound <literal>Session, that is, the getCurrentSession() functionality for easy context propagation, use the JTA UserTransaction API directly:"
msgstr "å¦‚æžœä½ å¸Œæœ›ä½¿ç”¨ä¸Žäº‹åŠ¡ç»‘å®šçš„ <literal>Session,也就是使用 getCurrentSession() æ¥ç®€åŒ–上下文管ç†ï¼Œä½ å°†ä¸å¾—ä¸ç›´æŽ¥ä½¿ç”¨ JTA UserTransaction API。 "
#. Tag: para
#, no-c-format
msgid "With CMT, transaction demarcation is completed in session bean deployment descriptors, not programmatically. The code is reduced to:"
msgstr "在 CMT æ–¹å¼ä¸‹ï¼Œäº‹åŠ¡å£°æ˜Žæ˜¯åœ¨ session bean 的部署æ述符ä¸ï¼Œè€Œä¸éœ€è¦ç¼–ç¨‹ã€‚å› æ¤ï¼Œä»£ç 被简化为:"
#. Tag: para
#, no-c-format
msgid "In a CMT/EJB, even rollback happens automatically. An unhandled <literal>RuntimeException thrown by a session bean method tells the container to set the global transaction to rollback. You do not need to use the Hibernate Transaction API at all with BMT or CMT, and you get automatic propagation of the \"current\" Session bound to the transaction. "
msgstr "在 CMT/EJB ä¸ç”šè‡³ä¼šè‡ªåŠ¨ rollbackï¼Œå› ä¸ºå‡è‹¥æœ‰æœªæ•èŽ·çš„ <literal>RuntimeException 从 session bean 方法ä¸æŠ›å‡ºï¼Œè¿™å°±ä¼šé€šçŸ¥å®¹å™¨æŠŠå…¨å±€äº‹åŠ¡å›žæ»šã€‚这就æ„味ç€ï¼Œåœ¨ BMT 或者 CMT ä¸ï¼Œä½ æ ¹æœ¬å°±ä¸éœ€è¦ä½¿ç”¨ Hibernate Transaction APIï¼Œä½ è‡ªåŠ¨å¾—åˆ°äº†ç»‘å®šåˆ°äº‹åŠ¡çš„â€œå½“å‰â€ Session。 "
#. Tag: para
#, no-c-format
msgid "When configuring Hibernate's transaction factory, choose <literal>org.hibernate.transaction.JTATransactionFactory if you use JTA directly (BMT), and org.hibernate.transaction.CMTTransactionFactory in a CMT session bean. Remember to also set hibernate.transaction.manager_lookup_class . Ensure that your hibernate.current_session_context_class is either unset (backwards compatibility), or is set to \"jta\" ."
msgstr "注æ„ï¼Œå½“ä½ é…ç½® Hibernate çš„ transaction factory 的时候,在直接使用 JTA 的时候(BMTï¼‰ï¼Œä½ åº”è¯¥é€‰æ‹© <literal>org.hibernate.transaction.JTATransactionFactory,在 CMT session bean ä¸é€‰æ‹© org.hibernate.transaction.CMTTransactionFactory 。记得也è¦è®¾ç½® hibernate.transaction.manager_lookup_class ã€‚è¿˜æœ‰ï¼Œç¡®è®¤ä½ çš„ hibernate.current_session_context_class 未设置(为了å‘下兼容),或者设置为 \"jta\" 。 "
#. Tag: para
#, no-c-format
msgid "The <literal>getCurrentSession() operation has one downside in a JTA environment. There is one caveat to the use of after_statement connection release mode, which is then used by default. Due to a limitation of the JTA spec, it is not possible for Hibernate to automatically clean up any unclosed ScrollableResults or Iterator instances returned by scroll() or iterate() . You must release the underlying database cursor by calling ScrollableResults.close() or Hibernate.close(Iterator) explicitly from a finally block. Most applications can easily avoid using scroll() or iterate() from the JTA or CMT code.)"
msgstr "<literal>getCurrentSession()在 JTA 环境ä¸æœ‰ä¸€ä¸ªå¼Šç«¯ã€‚对 after_statement 连接释放方å¼æœ‰ä¸€ä¸ªè¦å‘Šï¼Œè¿™æ˜¯è¢«é»˜è®¤ä½¿ç”¨çš„ã€‚å› ä¸º JTA è§„èŒƒçš„ä¸€ä¸ªå¾ˆæ„šè ¢çš„é™åˆ¶ï¼ŒHibernate ä¸å¯èƒ½è‡ªåŠ¨æ¸…ç†ä»»ä½•æœªå…³é—çš„ ScrollableResults 或者Iterator ,它们是由 scroll() 或 iterate() äº§ç”Ÿçš„ã€‚ä½ must 通过在 finally å—ä¸ï¼Œæ˜¾å¼è°ƒç”¨ ScrollableResults.close() 或者 Hibernate.close(Iterator) 方法æ¥é‡Šæ”¾åº•å±‚æ•°æ®åº“æ¸¸æ ‡ã€‚ï¼ˆå½“ç„¶ï¼Œå¤§éƒ¨åˆ†ç¨‹åºå®Œå…¨å¯ä»¥å¾ˆå®¹æ˜“çš„é¿å…在 JTA 或 CMT 代ç ä¸å‡ºçŽ° scroll() 或 iterate() 。) "
#. Tag: title
#, no-c-format
msgid "Exception handling"
msgstr "异常处ç†"
#. Tag: para
#, no-c-format
msgid "If the <literal>Session throws an exception, including any SQLException , immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable. Ensure that the Session will be closed by calling close() in a finally block."
msgstr "如果 <literal>Session 抛出异常(包括任何 SQLException ï¼‰ï¼Œä½ åº”è¯¥ç«‹å³å›žæ»šæ•°æ®åº“事务,调用 Session.close() ,丢弃该 Session 实例。Session çš„æŸäº›æ–¹æ³•å¯èƒ½ä¼šå¯¼è‡´ session 处于ä¸ä¸€è‡´çš„状æ€ã€‚所有由 Hibernate 抛出的异常都视为ä¸å¯ä»¥æ¢å¤çš„。确ä¿åœ¨ finally 代ç å—ä¸è°ƒç”¨ close() 方法,以关é—掉 Session 。"
#. Tag: para
#, no-c-format
msgid "The <literal>HibernateException, which wraps most of the errors that can occur in a Hibernate persistence layer, is an unchecked exception. It was not in older versions of Hibernate. In our opinion, we should not force the application developer to catch an unrecoverable exception at a low layer. In most systems, unchecked and fatal exceptions are handled in one of the first frames of the method call stack (i.e., in higher layers) and either an error message is presented to the application user or some other appropriate action is taken. Note that Hibernate might also throw other unchecked exceptions that are not a HibernateException . These are not recoverable and appropriate action should be taken."
msgstr "<literal>HibernateException 是一个éžæ£€æŸ¥æœŸå¼‚常(这ä¸åŒäºŽ Hibernate è€çš„版本),它å°è£…了 Hibernate æŒä¹…层å¯èƒ½å‡ºçŽ°çš„大多数错误。我们的观点是,ä¸åº”该强迫应用程åºå¼€å‘人员 在底层æ•èŽ·æ— 法æ¢å¤çš„异常。在大多数软件系统ä¸ï¼Œéžæ£€æŸ¥æœŸå¼‚常和致命异常都是在相应方法调用 çš„å †æ ˆçš„é¡¶å±‚è¢«å¤„ç†çš„(也就是说,在软件上é¢çš„逻辑层),并且æ供一个错误信æ¯ç»™åº”用软件的用户 (或者采å–其他æŸäº›ç›¸åº”çš„æ“作)。请注æ„,Hibernate 也有å¯èƒ½æŠ›å‡ºå…¶ä»–并ä¸å±žäºŽ HibernateException çš„éžæ£€æŸ¥æœŸå¼‚常。这些异常åŒæ ·ä¹Ÿæ˜¯æ— 法æ¢å¤çš„,应该 采å–æŸäº›ç›¸åº”çš„æ“作去处ç†ã€‚"
#. Tag: para
#, no-c-format
msgid "Hibernate wraps <literal>SQLExceptions thrown while interacting with the database in a JDBCException . In fact, Hibernate will attempt to convert the exception into a more meaningful subclass of JDBCException . The underlying SQLException is always available via JDBCException.getCause() . Hibernate converts the SQLException into an appropriate JDBCException subclass using the SQLExceptionConverter attached to the SessionFactory . By default, the SQLExceptionConverter is defined by the configured dialect. However, it is also possible to plug in a custom implementation. See the javadocs for the SQLExceptionConverterFactory class for details. The standard JDBCException subtypes are:"
msgstr "在和数æ®åº“进行交互时,Hibernate 把æ•èŽ·çš„ <literal>SQLException å°è£…为 Hibernate çš„ JDBCException 。事实上,Hibernate å°è¯•æŠŠå¼‚常转æ¢ä¸ºæ›´æœ‰å®žé™…å«ä¹‰çš„ JDBCException 异常的å类。底层的 SQLException å¯ä»¥é€šè¿‡ JDBCException.getCause() æ¥å¾—到。Hibernate 通过使用关è”到 SessionFactory 上的 SQLExceptionConverter æ¥æŠŠ SQLException 转æ¢ä¸ºä¸€ä¸ªå¯¹åº”çš„ JDBCException 异常的å类。默认情况下,SQLExceptionConverter å¯ä»¥é€šè¿‡é…ç½® dialect 选项指定;æ¤å¤–,也å¯ä»¥ä½¿ç”¨ç”¨æˆ·è‡ªå®šä¹‰çš„实现类(å‚考 javadocs SQLExceptionConverterFactory ç±»æ¥äº†è§£è¯¦æƒ…ï¼‰ã€‚æ ‡å‡†çš„ JDBCException å类型是: "
#. Tag: para
#, no-c-format
msgid "<literal>JDBCConnectionException: indicates an error with the underlying JDBC communication."
msgstr "<literal>JDBCConnectionException:指明底层的 JDBC 通讯出现错误。"
#. Tag: para
#, no-c-format
msgid "<literal>SQLGrammarException: indicates a grammar or syntax problem with the issued SQL."
msgstr "<literal>SQLGrammarException:指明å‘é€çš„ SQL è¯å¥çš„è¯æ³•æˆ–è€…æ ¼å¼é”™è¯¯ã€‚"
#. Tag: para
#, no-c-format
msgid "<literal>ConstraintViolationException: indicates some form of integrity constraint violation."
msgstr "<literal>ConstraintViolationException:指明æŸç§ç±»åž‹çš„约æŸè¿ä¾‹é”™è¯¯"
#. Tag: para
#, no-c-format
msgid "<literal>LockAcquisitionException: indicates an error acquiring a lock level necessary to perform the requested operation."
msgstr "<literal>LockAcquisitionException:指明了在执行请求æ“作时,获å–所需的é”级别时出现的错误。"
#. Tag: para
#, no-c-format
msgid "<literal>GenericJDBCException: a generic exception which did not fall into any of the other categories."
msgstr "<literal>GenericJDBCException:ä¸å±žäºŽä»»ä½•å…¶ä»–ç§ç±»çš„原生异常。"
#. Tag: title
#, no-c-format
msgid "Transaction timeout"
msgstr "事务超时"
#. Tag: para
#, no-c-format
msgid "An important feature provided by a managed environment like EJB, that is never provided for non-managed code, is transaction timeout. Transaction timeouts ensure that no misbehaving transaction can indefinitely tie up resources while returning no response to the user. Outside a managed (JTA) environment, Hibernate cannot fully provide this functionality. However, Hibernate can at least control data access operations, ensuring that database level deadlocks and queries with huge result sets are limited by a defined timeout. In a managed environment, Hibernate can delegate transaction timeout to JTA. This functionality is abstracted by the Hibernate <literal>Transaction object."
msgstr "EJB è¿™æ ·çš„æ‰˜ç®¡çŽ¯å¢ƒæœ‰ä¸€é¡¹æžä¸ºé‡è¦çš„特性,而它从未在éžæ‰˜ç®¡çŽ¯å¢ƒä¸æ供过,那就是事务超时。在出现错误的事务行为的时候,超时å¯ä»¥ç¡®ä¿ä¸ä¼šæ— é™æŒ‚起资æºã€å¯¹ç”¨æˆ·æ²¡æœ‰äº¤ä»£ã€‚在托管(JTA)环境之外,Hibernate æ— æ³•å®Œå…¨æ供这一功能。但是,Hiberante 至少å¯ä»¥æŽ§åˆ¶æ•°æ®è®¿é—®ï¼Œç¡®ä¿æ•°æ®åº“级别的æ»é”,和返回巨大结果集的查询被é™å®šåœ¨ä¸€ä¸ªè§„定的时间内。在托管环境ä¸ï¼ŒHibernate 会把事务超时转交给 JTA。这一功能通过 Hibernate <literal>Transaction 对象进行抽象。 "
#. Tag: para
#, no-c-format
msgid "<literal>setTimeout() cannot be called in a CMT bean, where transaction timeouts must be defined declaratively."
msgstr "æ³¨æ„ <literal>setTimeout() ä¸åº”该在 CMT bean ä¸è°ƒç”¨ï¼Œæ¤æ—¶äº‹åŠ¡è¶…时值应该是被声明å¼å®šä¹‰çš„。 "
#. Tag: title
#, no-c-format
msgid "Optimistic concurrency control"
msgstr "ä¹è§‚并å‘控制(Optimistic concurrency control)"
#. Tag: para
#, no-c-format
msgid "The only approach that is consistent with high concurrency and high scalability, is optimistic concurrency control with versioning. Version checking uses version numbers, or timestamps, to detect conflicting updates and to prevent lost updates. Hibernate provides three possible approaches to writing application code that uses optimistic concurrency. The use cases we discuss are in the context of long conversations, but version checking also has the benefit of preventing lost updates in single database transactions."
msgstr "唯一能够åŒæ—¶ä¿æŒé«˜å¹¶å‘和高å¯ä¼¸ç¼©æ€§çš„方法就是使用带版本化的ä¹è§‚并å‘控制。版本检查使用版本å·ã€ 或者时间戳æ¥æ£€æµ‹æ›´æ–°å†²çªï¼ˆå¹¶ä¸”防æ¢æ›´æ–°ä¸¢å¤±ï¼‰ã€‚Hibernate 为使用ä¹è§‚并å‘控制的代ç æ供了三ç§å¯ 能的方法,应用程åºåœ¨ç¼–写这些代ç 时,å¯ä»¥é‡‡ç”¨å®ƒä»¬ã€‚我们已ç»åœ¨å‰é¢åº”用程åºå¯¹è¯é‚£éƒ¨åˆ†å±•ç¤ºäº† ä¹è§‚并å‘控制的应用场景,æ¤å¤–,在å•ä¸ªæ•°æ®åº“事务范围内,版本检查也æ供了防æ¢æ›´æ–°ä¸¢å¤±çš„好处。 "
#. Tag: title
#, no-c-format
msgid "Application version checking"
msgstr "应用程åºçº§åˆ«çš„版本检查(Application version checking)"
#. Tag: para
#, no-c-format
msgid "In an implementation without much help from Hibernate, each interaction with the database occurs in a new <literal>Session and the developer is responsible for reloading all persistent instances from the database before manipulating them. The application is forced to carry out its own version checking to ensure conversation transaction isolation. This approach is the least efficient in terms of database access. It is the approach most similar to entity EJBs."
msgstr "未能充分利用 Hibernate 功能的实现代ç ä¸ï¼Œæ¯æ¬¡å’Œæ•°æ®åº“交互都需è¦ä¸€ä¸ªæ–°çš„ <literal>Session,而且开å‘人员必须在显示数æ®ä¹‹å‰ä»Žæ•°æ®åº“ä¸é‡æ–°è½½å…¥æ‰€æœ‰çš„æŒä¹…化对象实例。这ç§æ–¹å¼è¿«ä½¿åº”用程åºè‡ªå·±å®žçŽ°ç‰ˆæœ¬æ£€æŸ¥æ¥ç¡®ä¿å¯¹è¯äº‹åŠ¡çš„隔离,从数æ®è®¿é—®çš„角度æ¥è¯´æ˜¯æœ€ä½Žæ•ˆçš„。这ç§ä½¿ç”¨æ–¹å¼å’Œ entity EJB 最相似。 "
#. Tag: para
#, no-c-format
msgid "The <literal>version property is mapped using <version> , and Hibernate will automatically increment it during flush if the entity is dirty."
msgstr "<literal>version 属性使用 <version> æ¥æ˜ 射,如果对象是è„æ•°æ®ï¼Œåœ¨åŒæ¥çš„时候,Hibernate ä¼šè‡ªåŠ¨å¢žåŠ ç‰ˆæœ¬å·ã€‚"
#. Tag: para
#, no-c-format
msgid "If you are operating in a low-data-concurrency environment, and do not require version checking, you can use this approach and skip the version check. In this case, <emphasis>last commit wins is the default strategy for long conversations. Be aware that this might confuse the users of the application, as they might experience lost updates without error messages or a chance to merge conflicting changes."
msgstr "å½“ç„¶ï¼Œå¦‚æžœä½ çš„åº”ç”¨æ˜¯åœ¨ä¸€ä¸ªä½Žæ•°æ®å¹¶å‘环境下,并ä¸éœ€è¦ç‰ˆæœ¬æ£€æŸ¥çš„è¯ï¼Œä½ ç…§æ ·å¯ä»¥ä½¿ç”¨è¿™ç§æ–¹å¼ï¼Œåªä¸è¿‡è·³è¿‡ç‰ˆæœ¬æ£€æŸ¥å°±æ˜¯äº†ã€‚在这ç§æƒ…况下,<emphasis>最晚æ交生效 (last commit wins ï¼‰å°±æ˜¯ä½ çš„é•¿å¯¹è¯çš„默认处ç†ç–略。请记ä½è¿™ç§ç–ç•¥å¯èƒ½ä¼šè®©åº”ç”¨è½¯ä»¶çš„ç”¨æˆ·æ„Ÿåˆ°å›°æƒ‘ï¼Œå› ä¸ºä»–ä»¬æœ‰å¯èƒ½ä¼šç¢°ä¸Šæ›´æ–°ä¸¢å¤±æŽ‰å´æ²¡æœ‰å‡ºé”™ä¿¡æ¯ï¼Œæˆ–者需è¦åˆå¹¶æ›´æ”¹å†²çªçš„情况。 "
#. Tag: para
#, no-c-format
msgid "Manual version checking is only feasible in trivial circumstances and not practical for most applications. Often not only single instances, but complete graphs of modified objects, have to be checked. Hibernate offers automatic version checking with either an extended <literal>Session or detached instances as the design paradigm."
msgstr "很明显,手工进行版本检查åªé€‚åˆäºŽæŸäº›è½¯ä»¶è§„模éžå¸¸å°çš„应用场景,对于大多数软件应用场景æ¥è¯´å¹¶ä¸çŽ°å®žã€‚通常情况下,ä¸ä»…是å•ä¸ªå¯¹è±¡å®žä¾‹éœ€è¦è¿›è¡Œç‰ˆæœ¬æ£€æŸ¥ï¼Œæ•´ä¸ªè¢«ä¿®æ”¹è¿‡çš„å…³è”对象图也都需è¦è¿›è¡Œç‰ˆæœ¬æ£€æŸ¥ã€‚ä½œä¸ºæ ‡å‡†è®¾è®¡èŒƒä¾‹ï¼ŒHibernate 使用扩展周期的 <literal>Session çš„æ–¹å¼ï¼Œæˆ–者脱管对象实例的方å¼æ¥æ供自动版本检查。 "
#. Tag: title
#, no-c-format
msgid "Extended session and automatic versioning"
msgstr "扩展周期的 session 和自动版本化"
#. Tag: para
#, no-c-format
msgid "A single <literal>Session instance and its persistent instances that are used for the whole conversation are known as session-per-conversation . Hibernate checks instance versions at flush time, throwing an exception if concurrent modification is detected. It is up to the developer to catch and handle this exception. Common options are the opportunity for the user to merge changes or to restart the business conversation with non-stale data."
msgstr "å•ä¸ª <literal>Session 实例和它所关è”的所有æŒä¹…化对象实例都被用于整个对è¯ï¼Œè¿™è¢«ç§°ä¸º session-per-conversation 。Hibernate 在åŒæ¥çš„时候进行对象实例的版本检查,如果检测到并å‘修改则抛出异常。由开å‘人员æ¥å†³å®šæ˜¯å¦éœ€è¦æ•èŽ·å’Œå¤„ç†è¿™ä¸ªå¼‚常(通常的抉择是给用户 æ供一个åˆå¹¶æ›´æ”¹ï¼Œæˆ–è€…åœ¨æ— è„æ•°æ®æƒ…况下é‡æ–°è¿›è¡Œä¸šåŠ¡å¯¹è¯çš„机会)。 "
#. Tag: para
#, no-c-format
msgid "The <literal>Session is disconnected from any underlying JDBC connection when waiting for user interaction. This approach is the most efficient in terms of database access. The application does not version check or reattach detached instances, nor does it have to reload instances in every database transaction."
msgstr "在ç‰å¾…用户交互的时候, <literal>Session æ–开底层的 JDBC 连接。这ç§æ–¹å¼ä»¥æ•°æ®åº“访问的角度æ¥è¯´æ˜¯æœ€é«˜æ•ˆçš„æ–¹å¼ã€‚应用程åºä¸éœ€è¦å…³å¿ƒç‰ˆæœ¬æ£€æŸ¥æˆ–脱管对象实例的é‡æ–°å…³è”,在æ¯ä¸ªæ•°æ®åº“事务ä¸ï¼Œåº”用程åºä¹Ÿä¸éœ€è¦è½½å…¥è¯»å–对象实例。 "
#. Tag: para
#, no-c-format
msgid "The <literal>foo object knows which Session it was loaded in. Beginning a new database transaction on an old session obtains a new connection and resumes the session. Committing a database transaction disconnects a session from the JDBC connection and returns the connection to the pool. After reconnection, to force a version check on data you are not updating, you can call Session.lock() with LockMode.READ on any objects that might have been updated by another transaction. You do not need to lock any data that you are updating. Usually you would set FlushMode.MANUAL on an extended Session , so that only the last database transaction cycle is allowed to actually persist all modifications made in this conversation. Only this last database transaction will include the flush() operation, and then close() the session to end the conversation."
msgstr "<literal>foo 对象知é“它是在哪个 Session ä¸è¢«è£…入的。在一个旧 session ä¸å¼€å¯ä¸€ä¸ªæ–°çš„æ•°æ®åº“事务,会导致 session 获å–一个新的连接,并æ¢å¤ session 的功能。将数æ®åº“事务æ交,使得 session 从 JDBC 连接æ–开,并将æ¤è¿žæŽ¥äº¤è¿˜ç»™è¿žæŽ¥æ± 。在é‡æ–°è¿žæŽ¥ä¹‹åŽï¼Œè¦å¼ºåˆ¶å¯¹ä½ 没有更新的数æ®è¿›è¡Œä¸€æ¬¡ç‰ˆæœ¬æ£€æŸ¥ï¼Œä½ å¯ä»¥å¯¹æ‰€æœ‰å¯èƒ½è¢«å…¶ä»–事务修改过的对象,使用å‚æ•° LockMode.READ æ¥è°ƒç”¨ Session.lock() ã€‚ä½ ä¸ç”¨ lock ä»»ä½•ä½ æ£åœ¨ æ›´æ–°çš„æ•°æ®ã€‚ä¸€èˆ¬ä½ ä¼šåœ¨æ‰©å±•çš„ Session 上设置 FlushMode.NEVER ï¼Œå› æ¤åªæœ‰æœ€åŽä¸€ä¸ªæ•°æ®åº“事务循环æ‰ä¼šçœŸæ£çš„把整个对è¯ä¸å‘生的修改å‘é€åˆ°æ•°æ®åº“ã€‚å› æ¤ï¼Œåªæœ‰è¿™æœ€åŽä¸€æ¬¡æ•°æ®åº“事务æ‰ä¼šåŒ…å« flush() æ“作,然åŽåœ¨æ•´ä¸ªå¯¹è¯ç»“æŸåŽï¼Œè¿˜è¦ close() 这个 session。 "
#. Tag: para
#, no-c-format
msgid "This pattern is problematic if the <literal>Session is too big to be stored during user think time (for example, an HttpSession should be kept as small as possible). As the Session is also the first-level cache and contains all loaded objects, we can probably use this strategy only for a few request/response cycles. Use a Session only for a single conversation as it will soon have stale data."
msgstr "如果在用户æ€è€ƒçš„过程ä¸ï¼Œ<literal>Session å› ä¸ºå¤ªå¤§äº†è€Œä¸èƒ½ä¿å˜ï¼Œé‚£ä¹ˆè¿™ç§æ¨¡å¼æ˜¯æœ‰é—®é¢˜çš„。举例æ¥è¯´ï¼Œä¸€ä¸ª HttpSession 应该尽å¯èƒ½çš„å°ã€‚由于 Session 是一级缓å˜ï¼Œå¹¶ä¸”ä¿æŒäº†æ‰€æœ‰è¢«è½½å…¥è¿‡çš„å¯¹è±¡ï¼Œå› æ¤æˆ‘们åªåº”该在那些少é‡çš„ request/response 情况下使用这ç§ç–ç•¥ã€‚ä½ åº”è¯¥åªæŠŠä¸€ä¸ª Session 用于å•ä¸ªå¯¹è¯ï¼Œå› 为它很快就会出现è„æ•°æ®ã€‚ "
#. Tag: title
#, no-c-format
msgid "Note"
msgstr "注æ„"
#. Tag: para
#, no-c-format
msgid "Earlier versions of Hibernate required explicit disconnection and reconnection of a <literal>Session. These methods are deprecated, as beginning and ending a transaction has the same effect."
msgstr "注æ„,早期的 Hibernate 版本需è¦æ˜Žç¡®çš„对 <literal>Session 进行 disconnect å’Œ reconnect。这些方法现在已ç»è¿‡æ—¶äº†ï¼Œæ‰“开事务和关é—事务会起到åŒæ ·çš„效果。"
#. Tag: para
#, no-c-format
msgid "Keep the disconnected <literal>Session close to the persistence layer. Use an EJB stateful session bean to hold the Session in a three-tier environment. Do not transfer it to the web layer, or even serialize it to a separate tier, to store it in the HttpSession ."
msgstr "æ¤å¤–,也请注æ„ï¼Œä½ åº”è¯¥è®©ä¸Žæ•°æ®åº“连接æ–开的 <literal>Session 对æŒä¹…层ä¿æŒå…³é—状æ€ã€‚æ¢å¥è¯è¯´ï¼Œåœ¨ä¸‰å±‚环境ä¸ï¼Œä½¿ç”¨æœ‰çŠ¶æ€çš„ EJB session bean æ¥æŒ 有Session , 而ä¸è¦æŠŠå®ƒä¼ 递到 web 层(甚至把它åºåˆ—化到一个å•ç‹¬çš„层),ä¿å˜åœ¨ HttpSession ä¸ã€‚ "
#. Tag: para
#, no-c-format
msgid "The extended session pattern, or <emphasis>session-per-conversation, is more difficult to implement with automatic current session context management. You need to supply your own implementation of the CurrentSessionContext for this. See the Hibernate Wiki for examples."
msgstr "扩展 session 模å¼ï¼Œæˆ–者被称为<emphasis>æ¯æ¬¡å¯¹è¯ä¸€ä¸ªsession(session-per-conversation),自动管ç†å½“å‰ session 上下文è”ç”¨çš„æ—¶å€™ä¼šæ›´å›°éš¾ã€‚ä½ éœ€è¦æä¾›ä½ è‡ªå·±çš„ CurrentSessionContext 实现。请å‚阅 Hibernate Wiki 以获得示例。 "
#. Tag: title
#, no-c-format
msgid "Detached objects and automatic versioning"
msgstr "脱管对象(deatched object)和自动版本化"
#. Tag: para
#, no-c-format
msgid "Each interaction with the persistent store occurs in a new <literal>Session. However, the same persistent instances are reused for each interaction with the database. The application manipulates the state of detached instances originally loaded in another Session and then reattaches them using Session.update() , Session.saveOrUpdate() , or Session.merge() ."
msgstr "è¿™ç§æ–¹å¼ä¸‹ï¼Œä¸ŽæŒä¹…化å˜å‚¨çš„æ¯æ¬¡äº¤äº’都å‘生在一个新的 <literal>Session ä¸ã€‚然而,åŒä¸€æŒä¹…化对象实例å¯ä»¥åœ¨å¤šæ¬¡ä¸Žæ•°æ®åº“的交互ä¸é‡ç”¨ã€‚应用程åºæ“纵脱管对象实例 的状æ€ï¼Œè¿™ä¸ªè„±ç®¡å¯¹è±¡å®žä¾‹æœ€åˆæ˜¯åœ¨å¦ä¸€ä¸ª Session ä¸è½½å…¥çš„,然åŽè°ƒç”¨ Session.update() ,Session.saveOrUpdate() ,或者 Session.merge() æ¥é‡æ–°å…³è”该对象实例。"
#. Tag: para
#, no-c-format
msgid "Again, Hibernate will check instance versions during flush, throwing an exception if conflicting updates occurred."
msgstr "Hibernate 会å†ä¸€æ¬¡åœ¨åŒæ¥çš„时候检查对象实例的版本,如果å‘生更新冲çªï¼Œå°±æŠ›å‡ºå¼‚常。 "
#. Tag: para
#, no-c-format
msgid "You can also call <literal>lock() instead of update() , and use LockMode.READ (performing a version check and bypassing all caches) if you are sure that the object has not been modified."
msgstr "å¦‚æžœä½ ç¡®ä¿¡å¯¹è±¡æ²¡æœ‰è¢«ä¿®æ”¹è¿‡ï¼Œä½ ä¹Ÿå¯ä»¥è°ƒç”¨ <literal>lock() æ¥è®¾ç½® LockMode.READ (绕过所有的缓å˜ï¼Œæ‰§è¡Œç‰ˆæœ¬æ£€æŸ¥ï¼‰ï¼Œä»Žè€Œå–代 update() æ“作。 "
#. Tag: title
#, no-c-format
msgid "Customizing automatic versioning"
msgstr "定制自动版本化行为"
#. Tag: para
#, no-c-format
msgid "You can disable Hibernate's automatic version increment for particular properties and collections by setting the <literal>optimistic-lock mapping attribute to false . Hibernate will then no longer increment versions if the property is dirty."
msgstr "对于特定的属性和集åˆï¼Œé€šè¿‡ä¸ºå®ƒä»¬è®¾ç½®æ˜ 射属性 <literal>optimistic-lock 的值为 false ,æ¥ç¦æ¢ Hibernate çš„ç‰ˆæœ¬è‡ªåŠ¨å¢žåŠ ã€‚è¿™æ ·çš„è¯ï¼Œå¦‚果该属性è„æ•°æ®ï¼ŒHibernate å°†ä¸å†å¢žåŠ 版本å·ã€‚ "
#. Tag: para
#, no-c-format
msgid "Legacy database schemas are often static and cannot be modified. Or, other applications might access the same database and will not know how to handle version numbers or even timestamps. In both cases, versioning cannot rely on a particular column in a table. To force a version check with a comparison of the state of all fields in a row but without a version or timestamp property mapping, turn on <literal>optimistic-lock=\"all\" in the <class> mapping. This conceptually only works if Hibernate can compare the old and the new state (i.e., if you use a single long Session and not session-per-request-with-detached-objects)."
msgstr "é—留系统的数æ®åº“ Schema 通常是é™æ€çš„,ä¸å¯ä¿®æ”¹çš„。或者,其他应用程åºä¹Ÿå¯èƒ½è®¿é—®åŒä¸€æ•°æ®åº“ï¼Œæ ¹æœ¬æ— æ³•å¾—çŸ¥å¦‚ä½•å¤„ç†ç‰ˆæœ¬å·ï¼Œç”šè‡³æ—¶é—´æˆ³ã€‚在以上的所有场景ä¸ï¼Œå®žçŽ°ç‰ˆæœ¬åŒ–ä¸èƒ½ä¾é æ•°æ®åº“表的æŸä¸ªç‰¹å®šåˆ—。在 <literal><class> çš„æ˜ å°„ä¸è®¾ç½® optimistic-lock=\"all\" å¯ä»¥åœ¨æ²¡æœ‰ç‰ˆæœ¬æˆ–è€…æ—¶é—´æˆ³å±žæ€§æ˜ å°„çš„æƒ…å†µä¸‹å®žçŽ°ç‰ˆæœ¬æ£€æŸ¥ï¼Œæ¤æ—¶ Hibernate 将比较一行记录的æ¯ä¸ªå—段的状æ€ã€‚请注æ„,åªæœ‰å½“ Hibernate 能够比较新旧状æ€çš„情况下,这ç§æ–¹å¼æ‰èƒ½ç”Ÿæ•ˆï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œä½ 必须使用å•ä¸ªé•¿ç”Ÿå‘½å‘¨æœŸ Session 模å¼ï¼Œè€Œä¸èƒ½ä½¿ç”¨ session-per-request-with-detached-objects 模å¼ã€‚ "
#. Tag: para
#, no-c-format
msgid "Concurrent modification can be permitted in instances where the changes that have been made do not overlap. If you set <literal>optimistic-lock=\"dirty\" when mapping the <class> , Hibernate will only compare dirty fields during flush."
msgstr "有些情况下,åªè¦æ›´æ”¹ä¸å‘生交错,并å‘修改也是å…è®¸çš„ã€‚å½“ä½ åœ¨ <literal><class> çš„æ˜ å°„ä¸è®¾ç½® optimistic-lock=\"dirty\" ,Hibernate 在åŒæ¥çš„时候将åªæ¯”较有è„æ•°æ®çš„å—段。 "
#. Tag: para
#, no-c-format
msgid "In both cases, with dedicated version/timestamp columns or with a full/dirty field comparison, Hibernate uses a single <literal>UPDATE statement, with an appropriate WHERE clause, per entity to execute the version check and update the information. If you use transitive persistence to cascade reattachment to associated entities, Hibernate may execute unnecessary updates. This is usually not a problem, but on update triggers in the database might be executed even when no changes have been made to detached instances. You can customize this behavior by setting select-before-update=\"true\" in the <class> mapping, forcing Hibernate to SELECT the instance to ensure that changes did occur before updating the row."
msgstr "在以上所有场景ä¸ï¼Œä¸ç®¡æ˜¯ä¸“门设置一个版本/时间戳列,还是进行全部å—段/è„æ•°æ®å—段比较,Hibernate 都会针对æ¯ä¸ªå®žä½“对象å‘é€ä¸€æ¡ <literal>UPDATE(带有相应的 WHERE è¯å¥ )的 SQL è¯å¥æ¥æ‰§è¡Œç‰ˆæœ¬æ£€æŸ¥å’Œæ•°æ®æ›´æ–°ã€‚å¦‚æžœä½ å¯¹å…³è”实体 设置级è”å…³ç³»ä½¿ç”¨ä¼ æ’性æŒä¹…化(transitive persistence),那么 Hibernate å¯èƒ½ä¼šæ‰§è¡Œä¸å¿… è¦çš„updateè¯å¥ã€‚这通常ä¸æ˜¯ä¸ªé—®é¢˜ï¼Œä½†æ˜¯æ•°æ®åº“里é¢å¯¹ on update ç‚¹ç« çš„è§¦å‘器å¯èƒ½åœ¨è„±ç®¡å¯¹è±¡æ²¡æœ‰ä»»ä½•æ›´æ”¹çš„情况下被触å‘ã€‚å› æ¤ï¼Œä½ å¯ä»¥åœ¨ <class> çš„æ˜ å°„ä¸ï¼Œé€šè¿‡è®¾ç½®select-before-update=\"true\" æ¥å®šåˆ¶è¿™ä¸€è¡Œä¸ºï¼Œå¼ºåˆ¶ Hibernate SELECT 这个对象实例,从而ä¿è¯ï¼Œåœ¨æ›´æ–°è®°å½•ä¹‹å‰ï¼Œå¯¹è±¡çš„确是被修改过。 "
#. Tag: title
#, no-c-format
msgid "Pessimistic locking"
msgstr "悲观é”定(Pessimistic Locking) "
#. Tag: para
#, no-c-format
msgid "It is not intended that users spend much time worrying about locking strategies. It is usually enough to specify an isolation level for the JDBC connections and then simply let the database do all the work. However, advanced users may wish to obtain exclusive pessimistic locks or re-obtain locks at the start of a new transaction."
msgstr "用户其实并ä¸éœ€è¦èŠ±å¾ˆå¤šç²¾åŠ›åŽ»æ‹…心é”定ç–略的问题。通常情况下,åªè¦ä¸º JDBC 连接指定一下隔离级别,然åŽè®©æ•°æ®åº“去æžå®šä¸€åˆ‡å°±å¤Ÿäº†ã€‚然而,高级用户有时候希望进行一个排它的悲观é”定,或者在一个新的事务å¯åŠ¨çš„时候,é‡æ–°è¿›è¡Œé”定。 "
#. Tag: para
#, no-c-format
msgid "Hibernate will always use the locking mechanism of the database; it never lock objects in memory."
msgstr "Hibernate 总是使用数æ®åº“çš„é”定机制,从ä¸åœ¨å†…å˜ä¸é”定对象。"
#. Tag: para
#, no-c-format
msgid "The <literal>LockMode class defines the different lock levels that can be acquired by Hibernate. A lock is obtained by the following mechanisms:"
msgstr "ç±» <literal>LockMode 定义了 Hibernate 所需的ä¸åŒçš„é”定级别。一个é”定å¯ä»¥é€šè¿‡ä»¥ä¸‹çš„机制æ¥è®¾ç½®ï¼š"
#. Tag: para
#, no-c-format
msgid "<literal>LockMode.WRITE is acquired automatically when Hibernate updates or inserts a row."
msgstr "当 Hibernate 更新或者æ’入一行记录的时候,é”定级别自动设置为 <literal>LockMode.WRITE。"
#. Tag: para
#, no-c-format
msgid "<literal>LockMode.UPGRADE can be acquired upon explicit user request using SELECT ... FOR UPDATE on databases which support that syntax."
msgstr "当用户显å¼çš„使用数æ®åº“支æŒçš„ SQL æ ¼å¼ <literal>SELECT ... FOR UPDATE å‘é€ SQL 的时候,é”定级别设置为 LockMode.UPGRADE 。 "
#. Tag: para
#, no-c-format
msgid "<literal>LockMode.UPGRADE_NOWAIT can be acquired upon explicit user request using a SELECT ... FOR UPDATE NOWAIT under Oracle."
msgstr "当用户显å¼çš„使用 Oracle æ•°æ®åº“çš„ SQL è¯å¥ <literal>SELECT ... FOR UPDATE NOWAIT 的时候,é”定级别设置 LockMode.UPGRADE_NOWAIT 。 "
#. Tag: para
#, no-c-format
msgid "<literal>LockMode.READ is acquired automatically when Hibernate reads data under Repeatable Read or Serializable isolation level. It can be re-acquired by explicit user request."
msgstr "当 Hibernate 在“å¯é‡å¤è¯»â€æˆ–者是“åºåˆ—化â€æ•°æ®åº“隔离级别下读å–æ•°æ®çš„时候,é”定模å¼è‡ªåŠ¨è®¾ç½®ä¸º <literal>LockMode.READ。这ç§æ¨¡å¼ä¹Ÿå¯ä»¥é€šè¿‡ç”¨æˆ·æ˜¾å¼æŒ‡å®šè¿›è¡Œè®¾ç½®ã€‚ "
#. Tag: para
#, no-c-format
msgid "<literal>LockMode.NONE represents the absence of a lock. All objects switch to this lock mode at the end of a Transaction . Objects associated with the session via a call to update() or saveOrUpdate() also start out in this lock mode."
msgstr "<literal>LockMode.NONE ä»£è¡¨æ— éœ€é”定。在 Transaction 结æŸæ—¶ï¼Œ 所有的对象都切æ¢åˆ°è¯¥æ¨¡å¼ä¸Šæ¥ã€‚与 session 相关è”的对象通过调用 update() 或者 saveOrUpdate() 脱离该模å¼ã€‚"
#. Tag: para
#, no-c-format
msgid "The \"explicit user request\" is expressed in one of the following ways:"
msgstr "\"显å¼çš„用户指定\"å¯ä»¥é€šè¿‡ä»¥ä¸‹å‡ ç§æ–¹å¼ä¹‹ä¸€æ¥è¡¨ç¤ºï¼š"
#. Tag: para
#, no-c-format
msgid "A call to <literal>Session.load(), specifying a LockMode ."
msgstr "调用 <literal>Session.load() 的时候指定é”定模å¼ï¼ˆLockMode) 。"
#. Tag: para
#, no-c-format
msgid "A call to <literal>Session.lock()."
msgstr "调用 <literal>Session.lock()。"
#. Tag: para
#, no-c-format
msgid "A call to <literal>Query.setLockMode()."
msgstr "调用 <literal>Query.setLockMode()。"
#. Tag: para
#, no-c-format
msgid "If <literal>Session.load() is called with UPGRADE or UPGRADE_NOWAIT , and the requested object was not yet loaded by the session, the object is loaded using SELECT ... FOR UPDATE . If load() is called for an object that is already loaded with a less restrictive lock than the one requested, Hibernate calls lock() for that object."
msgstr "如果在 <literal>UPGRADE 或者 UPGRADE_NOWAIT é”定模å¼ä¸‹è°ƒç”¨ Session.load() ,并且è¦è¯»å–的对象尚未被 session 载入过,那么对象通过 SELECT ... FOR UPDATE è¿™æ ·çš„ SQL è¯å¥è¢«è½½å…¥ã€‚如果为一个对象调用 load() 方法时,该对象已ç»åœ¨å¦ä¸€ä¸ªè¾ƒå°‘é™åˆ¶çš„é”定模å¼ä¸‹è¢«è½½å…¥äº†ï¼Œé‚£ä¹ˆ Hibernate 就对该对象调用 lock() 方法。"
#. Tag: para
#, no-c-format
msgid "<literal>Session.lock() performs a version number check if the specified lock mode is READ , UPGRADE or UPGRADE_NOWAIT . In the case of UPGRADE or UPGRADE_NOWAIT , SELECT ... FOR UPDATE is used."
msgstr "如果指定的é”定模å¼æ˜¯ <literal>READ,UPGRADE 或 UPGRADE_NOWAIT ,那么 Session.lock() 就执行版本å·æ£€æŸ¥ã€‚(在 UPGRADE 或者 UPGRADE_NOWAIT é”定模å¼ä¸‹ï¼Œæ‰§è¡Œ SELECT ... FOR UPDATE è¿™æ ·çš„SQLè¯å¥ã€‚)"
#. Tag: para
#, no-c-format
msgid "If the requested lock mode is not supported by the database, Hibernate uses an appropriate alternate mode instead of throwing an exception. This ensures that applications are portable."
msgstr "如果数æ®åº“ä¸æ”¯æŒç”¨æˆ·è®¾ç½®çš„é”定模å¼ï¼ŒHibernate 将使用适当的替代模å¼ï¼ˆè€Œä¸æ˜¯æ‰”出异常)。这一点å¯ä»¥ç¡®ä¿åº”用程åºçš„å¯ç§»æ¤æ€§ã€‚ "
#. Tag: title
#, no-c-format
msgid "Connection release modes"
msgstr "连接释放模å¼ï¼ˆConnection Release Modes) "
#. Tag: para
#, no-c-format
msgid "One of the legacies of Hibernate 2.x JDBC connection management meant that a <literal>Session would obtain a connection when it was first required and then maintain that connection until the session was closed. Hibernate 3.x introduced the notion of connection release modes that would instruct a session how to handle its JDBC connections. The following discussion is pertinent only to connections provided through a configured ConnectionProvider . User-supplied connections are outside the breadth of this discussion. The different release modes are identified by the enumerated values of org.hibernate.ConnectionReleaseMode :"
msgstr "Hibernate 关于 JDBC 连接管ç†çš„旧(2.x)行为是,<literal>Session 在第一次需è¦çš„时候获å–一个连接,在 session å…³é—之å‰ä¸€ç›´ä¼šæŒæœ‰è¿™ä¸ªè¿žæŽ¥ã€‚Hibernate 引入了连接释放的概念,æ¥å‘Šè¯‰ session 如何处ç†å®ƒçš„ JDBC 连接。注æ„,下é¢çš„讨论åªé€‚用于采用é…ç½® ConnectionProvider æ¥æ供连接的情况,用户自己æä¾›çš„è¿žæŽ¥ä¸Žè¿™é‡Œçš„è®¨è®ºæ— å…³ã€‚é€šè¿‡ org.hibernate.ConnectionReleaseMode çš„ä¸åŒæžšä¸¾å€¼æ¥ä½¿ç”¨ä¸ç”¨çš„释放模å¼ï¼š"
#. Tag: para
#, no-c-format
msgid "<literal>ON_CLOSE: is the legacy behavior described above. The Hibernate session obtains a connection when it first needs to perform some JDBC access and maintains that connection until the session is closed."
msgstr "<literal>ON_CLOSE:基本上就是上é¢æ到的è€å¼è¡Œä¸ºã€‚Hibernate session 在第一次需è¦è¿›è¡Œ JDBC æ“作的时候获å–连接,然åŽæŒæœ‰å®ƒï¼Œç›´åˆ° session å…³é—。"
#. Tag: para
#, no-c-format
msgid "<literal>AFTER_TRANSACTION: releases connections after a org.hibernate.Transaction has been completed."
msgstr "<literal>AFTER_TRANSACTION:在 org.hibernate.Transaction 结æŸåŽé‡Šæ”¾è¿žæŽ¥ã€‚"
#. Tag: para
#, no-c-format
msgid "<literal>AFTER_STATEMENT (also referred to as aggressive release): releases connections after every statement execution. This aggressive releasing is skipped if that statement leaves open resources associated with the given session. Currently the only situation where this occurs is through the use of org.hibernate.ScrollableResults ."
msgstr "<literal>AFTER_STATEMENT(也被称åšç§¯æžé‡Šæ”¾ï¼‰ï¼šåœ¨æ¯ä¸€æ¡è¯å¥è¢«æ‰§è¡ŒåŽå°±é‡Šæ”¾è¿žæŽ¥ã€‚但å‡è‹¥è¯å¥ç•™ä¸‹äº†ä¸Ž session 相关的资æºï¼Œé‚£å°±ä¸ä¼šè¢«é‡Šæ”¾ã€‚ç›®å‰å”¯ä¸€çš„è¿™ç§æƒ…形就是使用 org.hibernate.ScrollableResults 。"
#. Tag: para
#, no-c-format
msgid "The configuration parameter <literal>hibernate.connection.release_mode is used to specify which release mode to use. The possible values are as follows:"
msgstr "<literal>hibernate.connection.release_mode é…ç½®å‚数用æ¥æŒ‡å®šä½¿ç”¨å“ªä¸€ç§é‡Šæ”¾æ¨¡å¼ã€‚å¯èƒ½çš„值有: "
#. Tag: para
#, no-c-format
msgid "<literal>auto (the default): this choice delegates to the release mode returned by the org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode() method. For JTATransactionFactory, this returns ConnectionReleaseMode.AFTER_STATEMENT; for JDBCTransactionFactory, this returns ConnectionReleaseMode.AFTER_TRANSACTION. Do not change this default behavior as failures due to the value of this setting tend to indicate bugs and/or invalid assumptions in user code."
msgstr "<literal>auto(默认):这一选择把释放模å¼å§”派给 org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode() 方法。对 JTATransactionFactory æ¥è¯´ï¼Œå®ƒä¼šè¿”回 ConnectionReleaseMode.AFTER_STATEMENT;对 JDBCTransactionFactory æ¥è¯´ï¼Œåˆ™æ˜¯ConnectionReleaseMode.AFTER_TRANSACTION。很少需è¦ä¿®æ”¹è¿™ä¸€é»˜è®¤è¡Œä¸ºï¼Œå› 为å‡è‹¥è®¾ç½®ä¸å½“ï¼Œå°±ä¼šå¸¦æ¥ bug,或者给用户代ç 带æ¥è¯¯å¯¼ã€‚"
#. Tag: para
#, no-c-format
msgid "<literal>on_close: uses ConnectionReleaseMode.ON_CLOSE. This setting is left for backwards compatibility, but its use is discouraged."
msgstr "<literal>on_close:使用 ConnectionReleaseMode.ON_CLOSE。这ç§æ–¹å¼æ˜¯ä¸ºäº†å‘下兼容的,但是已ç»å®Œå…¨ä¸è¢«é¼“励使用了。"
#. Tag: para
#, no-c-format
msgid "<literal>after_transaction: uses ConnectionReleaseMode.AFTER_TRANSACTION. This setting should not be used in JTA environments. Also note that with ConnectionReleaseMode.AFTER_TRANSACTION, if a session is considered to be in auto-commit mode, connections will be released as if the release mode were AFTER_STATEMENT."
msgstr "<literal>after_transaction:使用 ConnectionReleaseMode.AFTER_TRANSACTION。这一设置ä¸åº”该在 JTA 环境下使用。也è¦æ³¨æ„,使用 ConnectionReleaseMode.AFTER_TRANSACTION 的时候,å‡è‹¥session 处于 auto-commit 状æ€ï¼Œè¿žæŽ¥ä¼šåƒ AFTER_STATEMENT é‚£æ ·è¢«é‡Šæ”¾ã€‚"
#. Tag: para
#, no-c-format
msgid "<literal>after_statement: uses ConnectionReleaseMode.AFTER_STATEMENT. Additionally, the configured ConnectionProvider is consulted to see if it supports this setting (supportsAggressiveRelease() ). If not, the release mode is reset to ConnectionReleaseMode.AFTER_TRANSACTION. This setting is only safe in environments where we can either re-acquire the same underlying JDBC connection each time you make a call into ConnectionProvider.getConnection() or in auto-commit environments where it does not matter if we re-establish the same connection."
msgstr "<literal>after_statement:使用 ConnectionReleaseMode.AFTER_STATEMENT。除æ¤ä¹‹å¤–,会查询é…置的 ConnectionProvider ,是å¦å®ƒæ”¯æŒè¿™ä¸€è®¾ç½®ï¼ˆsupportsAggressiveRelease() )。å‡è‹¥ä¸æ”¯æŒï¼Œé‡Šæ”¾æ¨¡å¼ä¼šè¢«è®¾ç½®ä¸º ConnectionReleaseMode.AFTER_TRANSACTION。åªæœ‰åœ¨ä½ æ¯æ¬¡è°ƒç”¨ ConnectionProvider.getConnection() 获å–底层 JDBC 连接的时候,都å¯ä»¥ç¡®ä¿¡èŽ·å¾—åŒä¸€ä¸ªè¿žæŽ¥çš„时候,这一设置æ‰æ˜¯å®‰å…¨çš„;或者在 auto-commit 环境ä¸ï¼Œä½ å¯ä»¥ä¸ç®¡æ˜¯å¦æ¯æ¬¡éƒ½èŽ·å¾—åŒä¸€ä¸ªè¿žæŽ¥çš„时候,这æ‰æ˜¯å®‰å…¨çš„。"
#~ msgid "foo==bar"
#~ msgstr "foo==bar"
#~ msgid ""
#~ "<![CDATA[// Non-managed environment idiom\n"
#~ "Session sess = factory.openSession();\n"
#~ "Transaction tx = null;\n"
#~ "try {\n"
#~ " tx = sess.beginTransaction();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "\n"
#~ " tx.commit();\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " if (tx != null) tx.rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}\n"
#~ "finally {\n"
#~ " sess.close();\n"
#~ "}]]>"
#~ msgstr ""
#~ "<![CDATA[// Non-managed environment idiom\n"
#~ "Session sess = factory.openSession();\n"
#~ "Transaction tx = null;\n"
#~ "try {\n"
#~ " tx = sess.beginTransaction();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "\n"
#~ " tx.commit();\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " if (tx != null) tx.rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}\n"
#~ "finally {\n"
#~ " sess.close();\n"
#~ "}]]>"
#~ msgid ""
#~ "<![CDATA[// Non-managed environment idiom with getCurrentSession()\n"
#~ "try {\n"
#~ " factory.getCurrentSession().beginTransaction();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "\n"
#~ " factory.getCurrentSession().getTransaction().commit();\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " factory.getCurrentSession().getTransaction().rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}]]>"
#~ msgstr ""
#~ "<![CDATA[// Non-managed environment idiom with getCurrentSession()\n"
#~ "try {\n"
#~ " factory.getCurrentSession().beginTransaction();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "\n"
#~ " factory.getCurrentSession().getTransaction().commit();\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " factory.getCurrentSession().getTransaction().rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}]]>"
#~ msgid ""
#~ "<![CDATA[// BMT idiom\n"
#~ "Session sess = factory.openSession();\n"
#~ "Transaction tx = null;\n"
#~ "try {\n"
#~ " tx = sess.beginTransaction();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "\n"
#~ " tx.commit();\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " if (tx != null) tx.rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}\n"
#~ "finally {\n"
#~ " sess.close();\n"
#~ "}]]>"
#~ msgstr ""
#~ "<![CDATA[// BMT idiom\n"
#~ "Session sess = factory.openSession();\n"
#~ "Transaction tx = null;\n"
#~ "try {\n"
#~ " tx = sess.beginTransaction();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "\n"
#~ " tx.commit();\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " if (tx != null) tx.rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}\n"
#~ "finally {\n"
#~ " sess.close();\n"
#~ "}]]>"
#~ msgid ""
#~ "<![CDATA[// BMT idiom with getCurrentSession()\n"
#~ "try {\n"
#~ " UserTransaction tx = (UserTransaction)new InitialContext()\n"
#~ " .lookup(\"java:comp/UserTransaction\");\n"
#~ "\n"
#~ " tx.begin();\n"
#~ "\n"
#~ " // Do some work on Session bound to transaction\n"
#~ " factory.getCurrentSession().load(...);\n"
#~ " factory.getCurrentSession().persist(...);\n"
#~ "\n"
#~ " tx.commit();\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " tx.rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}]]>"
#~ msgstr ""
#~ "<![CDATA[// BMT idiom with getCurrentSession()\n"
#~ "try {\n"
#~ " UserTransaction tx = (UserTransaction)new InitialContext()\n"
#~ " .lookup(\"java:comp/UserTransaction\");\n"
#~ "\n"
#~ " tx.begin();\n"
#~ "\n"
#~ " // Do some work on Session bound to transaction\n"
#~ " factory.getCurrentSession().load(...);\n"
#~ " factory.getCurrentSession().persist(...);\n"
#~ "\n"
#~ " tx.commit();\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " tx.rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}]]>"
#~ msgid ""
#~ "<![CDATA[// CMT idiom\n"
#~ " Session sess = factory.getCurrentSession();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "]]>"
#~ msgstr ""
#~ "<![CDATA[// CMT idiom\n"
#~ " Session sess = factory.getCurrentSession();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "]]>"
#~ msgid ""
#~ "<![CDATA[\n"
#~ "Session sess = factory.openSession();\n"
#~ "try {\n"
#~ " //set transaction timeout to 3 seconds\n"
#~ " sess.getTransaction().setTimeout(3);\n"
#~ " sess.getTransaction().begin();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "\n"
#~ " sess.getTransaction().commit()\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " sess.getTransaction().rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}\n"
#~ "finally {\n"
#~ " sess.close();\n"
#~ "}]]>"
#~ msgstr ""
#~ "<![CDATA[\n"
#~ "Session sess = factory.openSession();\n"
#~ "try {\n"
#~ " //set transaction timeout to 3 seconds\n"
#~ " sess.getTransaction().setTimeout(3);\n"
#~ " sess.getTransaction().begin();\n"
#~ "\n"
#~ " // do some work\n"
#~ " ...\n"
#~ "\n"
#~ " sess.getTransaction().commit()\n"
#~ "}\n"
#~ "catch (RuntimeException e) {\n"
#~ " sess.getTransaction().rollback();\n"
#~ " throw e; // or display error message\n"
#~ "}\n"
#~ "finally {\n"
#~ " sess.close();\n"
#~ "}]]>"
#~ msgid ""
#~ "<![CDATA[// foo is an instance loaded by a previous Session\n"
#~ "session = factory.openSession();\n"
#~ "Transaction t = session.beginTransaction();\n"
#~ "\n"
#~ "int oldVersion = foo.getVersion();\n"
#~ "session.load( foo, foo.getKey() ); // load the current state\n"
#~ "if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException"
#~ "();\n"
#~ "foo.setProperty(\"bar\");\n"
#~ "\n"
#~ "t.commit();\n"
#~ "session.close();]]>"
#~ msgstr ""
#~ "<![CDATA[// foo is an instance loaded by a previous Session\n"
#~ "session = factory.openSession();\n"
#~ "Transaction t = session.beginTransaction();\n"
#~ "\n"
#~ "int oldVersion = foo.getVersion();\n"
#~ "session.load( foo, foo.getKey() ); // load the current state\n"
#~ "if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException"
#~ "();\n"
#~ "foo.setProperty(\"bar\");\n"
#~ "\n"
#~ "t.commit();\n"
#~ "session.close();]]>"
#~ msgid ""
#~ "<![CDATA[// foo is an instance loaded earlier by the old session\n"
#~ "Transaction t = session.beginTransaction(); // Obtain a new JDBC "
#~ "connection, start transaction\n"
#~ "\n"
#~ "foo.setProperty(\"bar\");\n"
#~ "\n"
#~ "session.flush(); // Only for last transaction in conversation\n"
#~ "t.commit(); // Also return JDBC connection\n"
#~ "session.close(); // Only for last transaction in conversation]]>"
#~ msgstr ""
#~ "<![CDATA[// foo is an instance loaded earlier by the old session\n"
#~ "Transaction t = session.beginTransaction(); // Obtain a new JDBC "
#~ "connection, start transaction\n"
#~ "\n"
#~ "foo.setProperty(\"bar\");\n"
#~ "\n"
#~ "session.flush(); // Only for last transaction in conversation\n"
#~ "t.commit(); // Also return JDBC connection\n"
#~ "session.close(); // Only for last transaction in conversation]]>"
#~ msgid ""
#~ "<![CDATA[// foo is an instance loaded by a previous Session\n"
#~ "foo.setProperty(\"bar\");\n"
#~ "session = factory.openSession();\n"
#~ "Transaction t = session.beginTransaction();\n"
#~ "session.saveOrUpdate(foo); // Use merge() if \"foo\" might have been "
#~ "loaded already\n"
#~ "t.commit();\n"
#~ "session.close();]]>"
#~ msgstr ""
#~ "<![CDATA[// foo is an instance loaded by a previous Session\n"
#~ "foo.setProperty(\"bar\");\n"
#~ "session = factory.openSession();\n"
#~ "Transaction t = session.beginTransaction();\n"
#~ "session.saveOrUpdate(foo); // Use merge() if \"foo\" might have been "
#~ "loaded already\n"
#~ "t.commit();\n"
#~ "session.close();]]>"
Other Hibernate examples (source code examples)
Here is a short list of links related to this Hibernate transactions.po source code file: