diff --git a/.github/workflows/release-on-tag.yml b/.github/workflows/release-on-tag.yml
new file mode 100644
index 000000000..3868a8f56
--- /dev/null
+++ b/.github/workflows/release-on-tag.yml
@@ -0,0 +1,23 @@
+name: Create Release on Tag
+
+on:
+  push:
+    tags:
+      - '*'
+
+jobs:
+  create_release:
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Create Release
+        uses: actions/create-release@v1
+        with:
+          tag_name: ${{ github.ref_name }}
+          release_name: ${{ github.ref_name }}
+          body: |
+            Release ${{ github.ref_name }} of GORM.
+          draft: false
+          prerelease: false
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 0601f0063..24eab55ab 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -176,17 +176,15 @@ jobs:
 
     services:
       mssql:
-        image: mcmoe/mssqldocker:latest
+        image: mcr.microsoft.com/mssql/server:2022-latest
         env:
+          TZ: Asia/Shanghai
           ACCEPT_EULA: Y
-          SA_PASSWORD: LoremIpsum86
-          MSSQL_DB: gorm
-          MSSQL_USER: gorm
-          MSSQL_PASSWORD: LoremIpsum86
+          MSSQL_SA_PASSWORD: LoremIpsum86
         ports:
           - 9930:1433
         options: >-
-          --health-cmd="/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P LoremIpsum86 -l 30 -Q \"SELECT 1\" || exit 1"
+          --health-cmd="/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P ${MSSQL_SA_PASSWORD} -N -C -l 30 -Q \"SELECT 1\" || exit 1"
           --health-start-period 10s
           --health-interval 10s
           --health-timeout 5s
@@ -208,7 +206,7 @@ jobs:
         key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('tests/go.mod') }}
 
     - name: Tests
-      run: GITHUB_ACTION=true GORM_DIALECT=sqlserver GORM_DSN="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" ./tests/tests_all.sh
+      run: GITHUB_ACTION=true GORM_DIALECT=sqlserver GORM_DSN="sqlserver://sa:LoremIpsum86@localhost:9930?database=master" ./tests/tests_all.sh
 
   tidb:
     strategy:
diff --git a/finisher_api.go b/finisher_api.go
index f97571ed0..6802945cc 100644
--- a/finisher_api.go
+++ b/finisher_api.go
@@ -4,6 +4,7 @@ import (
 	"database/sql"
 	"errors"
 	"fmt"
+	"hash/maphash"
 	"reflect"
 	"strings"
 
@@ -623,14 +624,15 @@ func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err er
 	if committer, ok := db.Statement.ConnPool.(TxCommitter); ok && committer != nil {
 		// nested transaction
 		if !db.DisableNestedTransaction {
-			err = db.SavePoint(fmt.Sprintf("sp%p", fc)).Error
+			spID := new(maphash.Hash).Sum64()
+			err = db.SavePoint(fmt.Sprintf("sp%d", spID)).Error
 			if err != nil {
 				return
 			}
 			defer func() {
 				// Make sure to rollback when panic, Block error or Commit error
 				if panicked || err != nil {
-					db.RollbackTo(fmt.Sprintf("sp%p", fc))
+					db.RollbackTo(fmt.Sprintf("sp%d", spID))
 				}
 			}()
 		}
diff --git a/schema/field.go b/schema/field.go
index a16c98ab0..bdc0b761c 100644
--- a/schema/field.go
+++ b/schema/field.go
@@ -12,6 +12,7 @@ import (
 	"time"
 
 	"github.com/jinzhu/now"
+
 	"gorm.io/gorm/clause"
 	"gorm.io/gorm/utils"
 )
@@ -922,7 +923,7 @@ func (field *Field) setupValuerAndSetter() {
 					if !reflectV.IsValid() {
 						field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem())
 					} else if reflectV.Kind() == reflect.Ptr && reflectV.IsNil() {
-						return
+						field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem())
 					} else if reflectV.Type().AssignableTo(field.FieldType) {
 						field.ReflectValueOf(ctx, value).Set(reflectV)
 					} else if reflectV.Kind() == reflect.Ptr {
diff --git a/tests/docker-compose.yml b/tests/compose.yml
similarity index 79%
rename from tests/docker-compose.yml
rename to tests/compose.yml
index 5a3a10f2a..66f2daee7 100644
--- a/tests/docker-compose.yml
+++ b/tests/compose.yml
@@ -1,5 +1,3 @@
-version: '3'
-
 services:
   mysql:
     image: 'mysql/mysql-server:latest'
@@ -20,16 +18,13 @@ services:
       - POSTGRES_USER=gorm
       - POSTGRES_PASSWORD=gorm
   mssql:
-    image: '${MSSQL_IMAGE:-mcmoe/mssqldocker}:latest'
+    image: '${MSSQL_IMAGE}:2022-latest'
     ports:
       - "127.0.0.1:9930:1433"
     environment:
       - TZ=Asia/Shanghai
       - ACCEPT_EULA=Y
-      - SA_PASSWORD=LoremIpsum86
-      - MSSQL_DB=gorm
-      - MSSQL_USER=gorm
-      - MSSQL_PASSWORD=LoremIpsum86
+      - MSSQL_SA_PASSWORD=LoremIpsum86
   tidb:
     image: 'pingcap/tidb:v6.5.0'
     ports:
diff --git a/tests/go.mod b/tests/go.mod
index 350d17946..44535b030 100644
--- a/tests/go.mod
+++ b/tests/go.mod
@@ -11,7 +11,7 @@ require (
 	gorm.io/driver/postgres v1.5.9
 	gorm.io/driver/sqlite v1.5.6
 	gorm.io/driver/sqlserver v1.5.3
-	gorm.io/gorm v1.25.10
+	gorm.io/gorm v1.25.12
 )
 
 require (
@@ -22,20 +22,18 @@ require (
 	github.com/golang-sql/sqlexp v0.1.0 // indirect
 	github.com/jackc/pgpassfile v1.0.0 // indirect
 	github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
-	github.com/jackc/pgx/v5 v5.6.0 // indirect
+	github.com/jackc/pgx/v5 v5.7.1 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/kr/text v0.2.0 // indirect
-	github.com/mattn/go-sqlite3 v1.14.22 // indirect
+	github.com/mattn/go-sqlite3 v1.14.23 // indirect
 	github.com/microsoft/go-mssqldb v1.7.2 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/rogpeppe/go-internal v1.12.0 // indirect
-	golang.org/x/crypto v0.24.0 // indirect
-	golang.org/x/text v0.16.0 // indirect
+	golang.org/x/crypto v0.27.0 // indirect
+	golang.org/x/text v0.18.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
 
 replace gorm.io/gorm => ../
 
-replace github.com/jackc/pgx/v5 => github.com/jackc/pgx/v5 v5.4.3
-
 replace github.com/microsoft/go-mssqldb => github.com/microsoft/go-mssqldb v1.7.0
diff --git a/tests/tests_all.sh b/tests/tests_all.sh
index ee9e76754..67c6938ea 100755
--- a/tests/tests_all.sh
+++ b/tests/tests_all.sh
@@ -21,13 +21,13 @@ if [[ -z $GITHUB_ACTION ]]; then
   then
     cd tests
     if [[ $(uname -a) == *" arm64" ]]; then
-      MSSQL_IMAGE=mcr.microsoft.com/azure-sql-edge docker-compose start || true
+      MSSQL_IMAGE=mcr.microsoft.com/azure-sql-edge docker compose up -d || true
       go install github.com/microsoft/go-sqlcmd/cmd/sqlcmd@latest || true
       SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF DB_ID('gorm') IS NULL CREATE DATABASE gorm" > /dev/null || true
       SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF SUSER_ID (N'gorm') IS NULL CREATE LOGIN gorm WITH PASSWORD = 'LoremIpsum86';" > /dev/null || true
       SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF USER_ID (N'gorm') IS NULL CREATE USER gorm FROM LOGIN gorm; ALTER SERVER ROLE sysadmin ADD MEMBER [gorm];" > /dev/null || true
     else
-      docker-compose start
+      MSSQL_IMAGE=mcr.microsoft.com/mssql/server docker compose up -d
     fi
     cd ..
   fi
diff --git a/tests/tests_test.go b/tests/tests_test.go
index a127734ed..e84162cd3 100644
--- a/tests/tests_test.go
+++ b/tests/tests_test.go
@@ -20,7 +20,7 @@ var DB *gorm.DB
 var (
 	mysqlDSN     = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local"
 	postgresDSN  = "user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai"
-	sqlserverDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
+	sqlserverDSN = "sqlserver://sa:LoremIpsum86@localhost:9930?database=master"
 	tidbDSN      = "root:@tcp(localhost:9940)/test?charset=utf8&parseTime=True&loc=Local"
 )
 
diff --git a/tests/transaction_test.go b/tests/transaction_test.go
index d2cbc9a95..9f0f067c8 100644
--- a/tests/transaction_test.go
+++ b/tests/transaction_test.go
@@ -297,6 +297,74 @@ func TestNestedTransactionWithBlock(t *testing.T) {
 	}
 }
 
+func TestDeeplyNestedTransactionWithBlockAndWrappedCallback(t *testing.T) {
+	transaction := func(ctx context.Context, db *gorm.DB, callback func(ctx context.Context, db *gorm.DB) error) error {
+		return db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
+			return callback(ctx, tx)
+		})
+	}
+	var (
+		user  = *GetUser("transaction-nested", Config{})
+		user1 = *GetUser("transaction-nested-1", Config{})
+		user2 = *GetUser("transaction-nested-2", Config{})
+	)
+
+	if err := transaction(context.Background(), DB, func(ctx context.Context, tx *gorm.DB) error {
+		tx.Create(&user)
+
+		if err := tx.First(&User{}, "name = ?", user.Name).Error; err != nil {
+			t.Fatalf("Should find saved record")
+		}
+
+		if err := transaction(ctx, tx, func(ctx context.Context, tx1 *gorm.DB) error {
+			tx1.Create(&user1)
+
+			if err := tx1.First(&User{}, "name = ?", user1.Name).Error; err != nil {
+				t.Fatalf("Should find saved record")
+			}
+
+			if err := transaction(ctx, tx1, func(ctx context.Context, tx2 *gorm.DB) error {
+				tx2.Create(&user2)
+
+				if err := tx2.First(&User{}, "name = ?", user2.Name).Error; err != nil {
+					t.Fatalf("Should find saved record")
+				}
+
+				return errors.New("inner rollback")
+			}); err == nil {
+				t.Fatalf("nested transaction has no error")
+			}
+
+			return errors.New("rollback")
+		}); err == nil {
+			t.Fatalf("nested transaction should returns error")
+		}
+
+		if err := tx.First(&User{}, "name = ?", user1.Name).Error; err == nil {
+			t.Fatalf("Should not find rollbacked record")
+		}
+
+		if err := tx.First(&User{}, "name = ?", user2.Name).Error; err != nil {
+			t.Fatalf("Should find saved record")
+		}
+		return nil
+	}); err != nil {
+		t.Fatalf("no error should return, but got %v", err)
+	}
+
+	if err := DB.First(&User{}, "name = ?", user.Name).Error; err != nil {
+		t.Fatalf("Should find saved record")
+	}
+
+	if err := DB.First(&User{}, "name = ?", user1.Name).Error; err == nil {
+		t.Fatalf("Should not find rollbacked parent record")
+	}
+
+	if err := DB.First(&User{}, "name = ?", user2.Name).Error; err != nil {
+		t.Fatalf("Should not find rollbacked nested record")
+	}
+}
+
 func TestDisabledNestedTransaction(t *testing.T) {
 	var (
 		user  = *GetUser("transaction-nested", Config{})