记一次因地球自转导致的数据库异常

  最近遇到一个Error:Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect).
  看字面意思是要更新的这一行记录已经被其他更新或者删除了。网上查了很多大家世代相传的资料。一般认为并发或者当前数据版本小于数据库数据的版本。但是我想了想,自己单机测试咋会出现这个问题。于是根据报错信息开始了漫长的调试研究过程。
  开发环境:springboot+jpa+MySQL;
  简化代码场景如下。

  1. 数据表:MySQL中有一个data表,Data有三个字段 自增型Id data_id,标记Data发布时间的data_publish_date,需要用户通过前端控件指定,标记用户具体信息的字符串data_info。
  2. 实体字段
@Entity
@Table(name="data")
public class Data{
   
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,下面是一个简单的用 WebGL 实现地球自转的 Demo: 首先,需要在 HTML 文件中创建一个 canvas 元素: ```html <canvas id="myCanvas" width="800" height="600"></canvas> ``` 然后,在 JavaScript 文件中获取 canvas 元素,并创建 WebGL 上下文: ```javascript const canvas = document.getElementById('myCanvas'); const gl = canvas.getContext('webgl'); ``` 接下来,需要编写着色器代码。这里我们需要两个着色器,一个用于顶点着色,一个用于片元着色。着色器代码如下: ```glsl // 顶点着色器代码 attribute vec3 aPosition; attribute vec2 aTexCoord; uniform mat4 uModelViewMatrix; uniform mat4 uProjectionMatrix; varying vec2 vTexCoord; void main() { gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0); vTexCoord = aTexCoord; } // 片元着色器代码 precision mediump float; uniform sampler2D uSampler; varying vec2 vTexCoord; void main() { gl_FragColor = texture2D(uSampler, vTexCoord); } ``` 接着,创建着色器程序,并将着色器代码编译链接: ```javascript // 顶点着色器代码 const vertexShaderSource = ` attribute vec3 aPosition; attribute vec2 aTexCoord; uniform mat4 uModelViewMatrix; uniform mat4 uProjectionMatrix; varying vec2 vTexCoord; void main() { gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0); vTexCoord = aTexCoord; } `; // 片元着色器代码 const fragmentShaderSource = ` precision mediump float; uniform sampler2D uSampler; varying vec2 vTexCoord; void main() { gl_FragColor = texture2D(uSampler, vTexCoord); } `; // 创建着色器程序 const shaderProgram = gl.createProgram(); // 编译链接顶点着色器 const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, vertexShaderSource); gl.compileShader(vertexShader); gl.attachShader(shaderProgram, vertexShader); // 编译链接片元着色器 const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, fragmentShaderSource); gl.compileShader(fragmentShader); gl.attachShader(shaderProgram, fragmentShader); // 链接着色器程序 gl.linkProgram(shaderProgram); ``` 然后,需要创建一个地球的顶点数据和纹理数据。这里我们使用了球体的顶点数据和 uv 坐标,以及地球的纹理图像。顶点数据和纹理数据如下: ```javascript // 球体顶点数据 const sphereVertices = []; const sphereUVs = []; const radius = 1; const segments = 32; const rings = 32; for (let r = 0; r < rings + 1; r++) { const theta = r * Math.PI / rings; const sinTheta = Math.sin(theta); const cosTheta = Math.cos(theta); for (let s = 0; s < segments + 1; s++) { const phi = s * 2 * Math.PI / segments; const sinPhi = Math.sin(phi); const cosPhi = Math.cos(phi); const x = cosPhi * sinTheta; const y = cosTheta; const z = sinPhi * sinTheta; sphereVertices.push(radius * x, radius * y, radius * z); sphereUVs.push(s / segments, r / rings); } } // 地球纹理图像 const textureImage = new Image(); textureImage.src = 'earth.jpg'; ``` 接下来,需要将顶点数据和纹理数据上传到 WebGL 中,并为着色器程序中的变量赋值: ```javascript // 将顶点数据和纹理数据上传到 WebGL 中 const positionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(sphereVertices), gl.STATIC_DRAW); const uvBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(sphereUVs), gl.STATIC_DRAW); // 为着色器程序中的变量赋值 const aPosition = gl.getAttribLocation(shaderProgram, 'aPosition'); gl.enableVertexAttribArray(aPosition); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0); const aTexCoord = gl.getAttribLocation(shaderProgram, 'aTexCoord'); gl.enableVertexAttribArray(aTexCoord); gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer); gl.vertexAttribPointer(aTexCoord, 2, gl.FLOAT, false, 0, 0); const uModelViewMatrix = gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'); const uProjectionMatrix = gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'); const uSampler = gl.getUniformLocation(shaderProgram, 'uSampler'); // 加载纹理图像 const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, textureImage); gl.generateMipmap(gl.TEXTURE_2D); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); ``` 最后,需要在循环中更新地球的旋转角度,并渲染场景: ```javascript let angle = 0; function render() { // 更新角度 angle += 0.01; // 计算模型视图矩阵和投影矩阵 const modelViewMatrix = mat4.create(); mat4.translate(modelViewMatrix, modelViewMatrix, [0, 0, -5]); mat4.rotateY(modelViewMatrix, modelViewMatrix, angle); const projectionMatrix = mat4.create(); mat4.perspective(projectionMatrix, 45 * Math.PI / 180, canvas.width / canvas.height, 0.1, 100); // 清空画布并绘制地球 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.useProgram(shaderProgram); gl.uniformMatrix4fv(uModelViewMatrix, false, modelViewMatrix); gl.uniformMatrix4fv(uProjectionMatrix, false, projectionMatrix); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture); gl.uniform1i(uSampler, 0); gl.drawArrays(gl.TRIANGLE_STRIP, 0, sphereVertices.length / 3); requestAnimationFrame(render); } render(); ``` 这样,一个简单的地球自转的 WebGL Demo 就完成了。完整代码如下:
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值