Proper MSSQL last_insert_id() scoping patch by abraxxa
Peter Rabbitson [Fri, 16 Jan 2009 10:29:16 +0000 (10:29 +0000)]
No tests as it is very hard to simulate the problematic behavior - it would only manifest if:
  1) An INSERT statement is issued from connection A
  2) An INSERT statement is issued from connection B
  3) last_insert_id is called from connection A

Without this patch the last id from the second INSERT will be returned in step 3
Tested with both DBICTEST_MSSQL_ODBC_DSN and DBICTEST_MSSQL_DSN against a MSSQL 2005

Changes
lib/DBIx/Class/Storage/DBI/MSSQL.pm

diff --git a/Changes b/Changes
index 55a45ee..263dc98 100644 (file)
--- a/Changes
+++ b/Changes
@@ -5,8 +5,10 @@ Revision history for DBIx::Class
         - 'result_class' resultset attribute, identical to result_class()
         - add 'undef_on_null_fk' option for relationship accessors of type 'single'. 
           This will prevent DBIC from querying the database if one or more of
-          the key columns IS NULL. Tests + docs (groditi)
-           - for 'belongs_to' rels, 'null_on_fk' defaults to true.
+          the key columns IS NULL
+        - for 'belongs_to' rels, 'undef_on_null_fk' defaults to true.
+        - fixed scope unaware last_insert_id fetching for MSSQL
+          (http://msdn.microsoft.com/en-us/library/ms190315.aspx)
 
 0.08099_05 2008-10-30 21:30:00 (UTC)
         - Rewritte of Storage::DBI::connect_info(), extended with an
index dcfe895..51c4e02 100644 (file)
@@ -7,7 +7,7 @@ use base qw/DBIx::Class::Storage::DBI/;
 
 sub _dbh_last_insert_id {
   my ($self, $dbh, $source, $col) = @_;
-  my ($id) = $dbh->selectrow_array('SELECT @@IDENTITY');
+  my ($id) = $dbh->selectrow_array('SELECT SCOPE_IDENTITY()');
   return $id;
 }